2 // FolioReaderFontsMenu.swift
5 // Created by Heberti Almeida on 27/08/15.
6 // Copyright (c) 2015 Folio Reader. All rights reserved.
11 public enum FolioReaderFont: Int {
17 public static func folioReaderFont(fontName: String) -> FolioReaderFont? {
18 var font: FolioReaderFont?
20 case "andada": font = .andada
21 case "lato": font = .lato
22 case "lora": font = .lora
23 case "raleway": font = .raleway
29 public var cssIdentifier: String {
31 case .andada: return "andada"
32 case .lato: return "lato"
33 case .lora: return "lora"
34 case .raleway: return "raleway"
39 public enum SliderType: Int{
44 var paramText: String{
55 var leftImage: UIImage{
58 return #imageLiteral(resourceName: "reader_font-small")
60 return #imageLiteral(resourceName: "reader_margin-small")
62 return #imageLiteral(resourceName: "reader_leading-small")
66 var rightImage: UIImage{
69 return #imageLiteral(resourceName: "reader_font-big")
71 return #imageLiteral(resourceName: "reader_margin-big")
73 return #imageLiteral(resourceName: "reader_leading-big")
78 public enum FolioReaderSliderParamSize: Int {
85 public static func folioReaderParamSize(fontSizeStringRepresentation: String, sliderType: SliderType) -> FolioReaderSliderParamSize? {
86 var paramSize: FolioReaderSliderParamSize?
87 let paramText = sliderType.paramText
88 switch fontSizeStringRepresentation {
89 case "\(paramText)SizeOne": paramSize = .xs
90 case "\(paramText)SizeTwo": paramSize = .s
91 case "\(paramText)SizeThree": paramSize = .m
92 case "\(paramText)SizeFour": paramSize = .l
93 case "\(paramText)SizeFive": paramSize = .xl
99 public func cssIdentifier(sliderType: SliderType) -> String {
100 let paramText = sliderType.paramText
102 case .xs: return "\(paramText)SizeOne"
103 case .s: return "\(paramText)SizeTwo"
104 case .m: return "\(paramText)SizeThree"
105 case .l: return "\(paramText)SizeFour"
106 case .xl: return "\(paramText)SizeFive"
111 class FolioReaderFontsMenu: UIViewController, SMSegmentViewDelegate, UIGestureRecognizerDelegate {
112 var menuView: UIView!
114 fileprivate var readerConfig: FolioReaderConfig
115 fileprivate var folioReader: FolioReader
117 init(folioReader: FolioReader, readerConfig: FolioReaderConfig) {
118 self.readerConfig = readerConfig
119 self.folioReader = folioReader
121 super.init(nibName: nil, bundle: nil)
124 required init?(coder aDecoder: NSCoder) {
125 fatalError("init(coder:) has not been implemented")
128 override func viewDidLoad() {
131 // Do any additional setup after loading the view.
132 self.view.backgroundColor = UIColor.clear
135 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(FolioReaderFontsMenu.tapGesture))
136 tapGesture.numberOfTapsRequired = 1
137 tapGesture.delegate = self
138 view.addGestureRecognizer(tapGesture)
141 // let visibleHeight: CGFloat = self.readerConfig.canChangeScrollDirection ? 222 : 170
142 let visibleHeight: CGFloat = self.readerConfig.canChangeScrollDirection ? 222 + 114 : 170 + 114
143 menuView = UIView(frame: CGRect(x: 0, y: view.frame.height-visibleHeight, width: view.frame.width, height: view.frame.height))
144 menuView.backgroundColor = self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white)
145 menuView.autoresizingMask = .flexibleWidth
146 menuView.layer.shadowColor = UIColor.black.cgColor
147 menuView.layer.shadowOffset = CGSize(width: 0, height: 0)
148 menuView.layer.shadowOpacity = 0.3
149 menuView.layer.shadowRadius = 6
150 menuView.layer.shadowPath = UIBezierPath(rect: menuView.bounds).cgPath
151 menuView.layer.rasterizationScale = UIScreen.main.scale
152 menuView.layer.shouldRasterize = true
153 view.addSubview(menuView)
155 let normalColor = UIColor(white: 0.5, alpha: 0.7)
156 let selectedColor = self.readerConfig.tintColor
157 let sun = UIImage(readerImageNamed: "icon-sun")
158 let moon = UIImage(readerImageNamed: "icon-moon")
159 let fontSmall = UIImage(readerImageNamed: "icon-font-small")
160 let fontBig = UIImage(readerImageNamed: "icon-font-big")
162 let sunNormal = sun?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
163 let moonNormal = moon?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
165 let sunSelected = sun?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
166 let moonSelected = moon?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
169 let dayNight = SMSegmentView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 55),
170 separatorColour: self.readerConfig.nightModeSeparatorColor,
173 keySegmentTitleFont: UIFont(name: "Avenir-Light", size: 17)!,
174 keySegmentOnSelectionColour: UIColor.clear,
175 keySegmentOffSelectionColour: UIColor.clear,
176 keySegmentOnSelectionTextColour: selectedColor,
177 keySegmentOffSelectionTextColour: normalColor,
178 keyContentVerticalMargin: 17 as AnyObject
180 dayNight.delegate = self
182 dayNight.addSegmentWithTitle(self.readerConfig.localizedFontMenuDay, onSelectionImage: sunSelected, offSelectionImage: sunNormal)
183 dayNight.addSegmentWithTitle(self.readerConfig.localizedFontMenuNight, onSelectionImage: moonSelected, offSelectionImage: moonNormal)
184 dayNight.selectSegmentAtIndex(self.folioReader.nightMode.hashValue)
185 menuView.addSubview(dayNight)
189 let line = UIView(frame: CGRect(x: 0, y: dayNight.frame.height+dayNight.frame.origin.y, width: view.frame.width, height: 1))
190 line.backgroundColor = self.readerConfig.nightModeSeparatorColor
191 menuView.addSubview(line)
194 let fontName = SMSegmentView(frame: CGRect(x: 15, y: line.frame.height+line.frame.origin.y, width: view.frame.width-30, height: 55),
195 separatorColour: UIColor.clear,
198 keySegmentOnSelectionColour: UIColor.clear,
199 keySegmentOffSelectionColour: UIColor.clear,
200 keySegmentOnSelectionTextColour: selectedColor,
201 keySegmentOffSelectionTextColour: normalColor,
202 keyContentVerticalMargin: 17 as AnyObject
204 fontName.delegate = self
207 fontName.addSegmentWithTitle("Andada", onSelectionImage: nil, offSelectionImage: nil)
208 fontName.addSegmentWithTitle("Lato", onSelectionImage: nil, offSelectionImage: nil)
209 fontName.addSegmentWithTitle("Lora", onSelectionImage: nil, offSelectionImage: nil)
210 fontName.addSegmentWithTitle("Raleway", onSelectionImage: nil, offSelectionImage: nil)
212 // fontName.segments[0].titleFont = UIFont(name: "Andada-Regular", size: 18)!
213 // fontName.segments[1].titleFont = UIFont(name: "Lato-Regular", size: 18)!
214 // fontName.segments[2].titleFont = UIFont(name: "Lora-Regular", size: 18)!
215 // fontName.segments[3].titleFont = UIFont(name: "Raleway-Regular", size: 18)!
217 fontName.selectSegmentAtIndex(self.folioReader.currentFont.rawValue)
218 menuView.addSubview(fontName)
221 let line2 = UIView(frame: CGRect(x: 0, y: fontName.frame.height+fontName.frame.origin.y, width: view.frame.width, height: 1))
222 line2.backgroundColor = self.readerConfig.nightModeSeparatorColor
223 menuView.addSubview(line2)
225 addSlider(sliderType: .font, topY: line2.frame.origin.y, selectedColor: selectedColor)
227 addSlider(sliderType: .margin, topY: line2.frame.origin.y + 57, selectedColor: selectedColor)
229 addSlider(sliderType: .interline, topY: line2.frame.origin.y + 114, selectedColor: selectedColor)
231 // // Font slider size
232 // let slider = HADiscreteSlider(frame: CGRect(x: 60, y: line2.frame.origin.y+2, width: view.frame.width-120, height: 55))
233 // slider.tickStyle = ComponentStyle.rounded
234 // slider.tickCount = 5
235 // slider.tickSize = CGSize(width: 8, height: 8)
237 // slider.thumbStyle = ComponentStyle.rounded
238 // slider.thumbSize = CGSize(width: 28, height: 28)
239 // slider.thumbShadowOffset = CGSize(width: 0, height: 2)
240 // slider.thumbShadowRadius = 3
241 // slider.thumbColor = selectedColor
243 // slider.backgroundColor = UIColor.clear
244 // slider.tintColor = self.readerConfig.nightModeSeparatorColor
245 // slider.minimumValue = 0
246 // slider.value = CGFloat(self.folioReader.currentFontSize.rawValue)
247 // slider.addTarget(self, action: #selector(FolioReaderFontsMenu.sliderValueChanged(_:)), for: UIControlEvents.valueChanged)
249 // // Force remove fill color
250 // slider.layer.sublayers?.forEach({ layer in
251 // layer.backgroundColor = UIColor.clear.cgColor
254 // menuView.addSubview(slider)
257 // let fontSmallView = UIImageView(frame: CGRect(x: 20, y: line2.frame.origin.y+14, width: 30, height: 30))
258 // fontSmallView.image = fontSmallNormal
259 // fontSmallView.contentMode = UIViewContentMode.center
260 // menuView.addSubview(fontSmallView)
262 // let fontBigView = UIImageView(frame: CGRect(x: view.frame.width-50, y: line2.frame.origin.y+14, width: 30, height: 30))
263 // fontBigView.image = fontBigNormal
264 // fontBigView.contentMode = UIViewContentMode.center
265 // menuView.addSubview(fontBigView)
267 // Only continues if user can change scroll direction
268 guard (self.readerConfig.canChangeScrollDirection == true) else {
273 // let line3 = UIView(frame: CGRect(x: 0, y: line2.frame.origin.y+56, width: view.frame.width, height: 1))
274 let line3 = UIView(frame: CGRect(x: 0, y: line2.frame.origin.y+171, width: view.frame.width, height: 1))
275 line3.backgroundColor = self.readerConfig.nightModeSeparatorColor
276 menuView.addSubview(line3)
278 let vertical = UIImage(readerImageNamed: "icon-menu-vertical")
279 let horizontal = UIImage(readerImageNamed: "icon-menu-horizontal")
280 let verticalNormal = vertical?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
281 let horizontalNormal = horizontal?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
282 let verticalSelected = vertical?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
283 let horizontalSelected = horizontal?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
286 let layoutDirection = SMSegmentView(frame: CGRect(x: 0, y: line3.frame.origin.y, width: view.frame.width, height: 55),
287 separatorColour: self.readerConfig.nightModeSeparatorColor,
290 keySegmentTitleFont: UIFont(name: "Avenir-Light", size: 17)!,
291 keySegmentOnSelectionColour: UIColor.clear,
292 keySegmentOffSelectionColour: UIColor.clear,
293 keySegmentOnSelectionTextColour: selectedColor,
294 keySegmentOffSelectionTextColour: normalColor,
295 keyContentVerticalMargin: 17 as AnyObject
297 layoutDirection.delegate = self
298 layoutDirection.tag = 3
299 layoutDirection.addSegmentWithTitle(self.readerConfig.localizedLayoutVertical, onSelectionImage: verticalSelected, offSelectionImage: verticalNormal)
300 layoutDirection.addSegmentWithTitle(self.readerConfig.localizedLayoutHorizontal, onSelectionImage: horizontalSelected, offSelectionImage: horizontalNormal)
302 var scrollDirection = FolioReaderScrollDirection(rawValue: self.folioReader.currentScrollDirection)
304 if scrollDirection == .defaultVertical && self.readerConfig.scrollDirection != .defaultVertical {
305 scrollDirection = self.readerConfig.scrollDirection
308 switch scrollDirection ?? .vertical {
309 case .vertical, .defaultVertical:
310 layoutDirection.selectSegmentAtIndex(FolioReaderScrollDirection.vertical.rawValue)
311 case .horizontal, .horizontalWithVerticalContent:
312 layoutDirection.selectSegmentAtIndex(FolioReaderScrollDirection.horizontal.rawValue)
314 menuView.addSubview(layoutDirection)
317 func addSlider(sliderType: SliderType, topY: CGFloat, selectedColor: UIColor){
319 let normalColor = UIColor(white: 0.5, alpha: 0.7)
322 let slider = HADiscreteSlider(frame: CGRect(x: 60, y: topY+2, width: view.frame.width-120, height: 55))
323 slider.tickStyle = ComponentStyle.rounded
325 slider.tickSize = CGSize(width: 8, height: 8)
327 slider.thumbStyle = ComponentStyle.rounded
328 slider.thumbSize = CGSize(width: 28, height: 28)
329 slider.thumbShadowOffset = CGSize(width: 0, height: 2)
330 slider.thumbShadowRadius = 3
331 slider.thumbColor = selectedColor
333 slider.backgroundColor = UIColor.clear
334 slider.tintColor = self.readerConfig.nightModeSeparatorColor
335 slider.minimumValue = 0
336 slider.tag = sliderType.rawValue
340 slider.value = CGFloat(self.folioReader.currentFontSize.rawValue)
342 slider.value = CGFloat(self.folioReader.currentMarginSize.rawValue)
344 slider.value = CGFloat(self.folioReader.currentInterlineSize.rawValue)
347 slider.addTarget(self, action: #selector(FolioReaderFontsMenu.sliderValueChanged(_:)), for: UIControlEvents.valueChanged)
349 // Force remove fill color
350 slider.layer.sublayers?.forEach({ layer in
351 layer.backgroundColor = UIColor.clear.cgColor
354 menuView.addSubview(slider)
357 let fontSmallView = UIImageView(frame: CGRect(x: 20, y: topY+14, width: 30, height: 30))
358 fontSmallView.image = sliderType.leftImage.imageTintColor(normalColor)
359 fontSmallView.contentMode = UIViewContentMode.center
360 menuView.addSubview(fontSmallView)
362 let fontBigView = UIImageView(frame: CGRect(x: view.frame.width-50, y: topY+14, width: 30, height: 30))
363 fontSmallView.image = sliderType.rightImage.imageTintColor(normalColor)
364 fontBigView.contentMode = UIViewContentMode.center
365 menuView.addSubview(fontBigView)
368 // MARK: - SMSegmentView delegate
370 func segmentView(_ segmentView: SMSegmentView, didSelectSegmentAtIndex index: Int) {
371 guard (self.folioReader.readerCenter?.currentPage) != nil else { return }
373 if segmentView.tag == 1 {
375 self.folioReader.nightMode = Bool(index == 1)
377 UIView.animate(withDuration: 0.6, animations: {
378 self.menuView.backgroundColor = (self.folioReader.nightMode ? self.readerConfig.nightModeBackground : UIColor.white)
381 } else if segmentView.tag == 2 {
383 self.folioReader.currentFont = FolioReaderFont(rawValue: index)!
385 } else if segmentView.tag == 3 {
387 guard self.folioReader.currentScrollDirection != index else {
391 self.folioReader.currentScrollDirection = index
395 // MARK: - Font slider changed
397 @objc func sliderValueChanged(_ sender: HADiscreteSlider) {
399 (self.folioReader.readerCenter?.currentPage != nil), let sliderType = SliderType(rawValue: sender.tag)
406 if let fontSize = FolioReaderSliderParamSize(rawValue: Int(sender.value)){
407 self.folioReader.currentFontSize = fontSize
410 if let marginSize = FolioReaderSliderParamSize(rawValue: Int(sender.value)){
411 self.folioReader.currentMarginSize = marginSize
414 if let interlineSize = FolioReaderSliderParamSize(rawValue: Int(sender.value)){
415 self.folioReader.currentInterlineSize = interlineSize
422 @objc func tapGesture() {
425 if (self.readerConfig.shouldHideNavigationOnTap == false) {
426 self.folioReader.readerCenter?.showBars()
430 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
431 if gestureRecognizer is UITapGestureRecognizer && touch.view == view {
437 // MARK: - Status Bar
439 override var prefersStatusBarHidden : Bool {
440 return (self.readerConfig.shouldHideNavigationOnTap == true)