added iOS source code
[wl-app.git] / iOS / Pods / FolioReaderKit / Source / FolioReaderFontsMenu.swift
1 //
2 //  FolioReaderFontsMenu.swift
3 //  FolioReaderKit
4 //
5 //  Created by Heberti Almeida on 27/08/15.
6 //  Copyright (c) 2015 Folio Reader. All rights reserved.
7 //
8
9 import UIKit
10
11 public enum FolioReaderFont: Int {
12     case andada = 0
13     case lato
14     case lora
15     case raleway
16
17     public static func folioReaderFont(fontName: String) -> FolioReaderFont? {
18         var font: FolioReaderFont?
19         switch fontName {
20         case "andada": font = .andada
21         case "lato": font = .lato
22         case "lora": font = .lora
23         case "raleway": font = .raleway
24         default: break
25         }
26         return font
27     }
28
29     public var cssIdentifier: String {
30         switch self {
31         case .andada: return "andada"
32         case .lato: return "lato"
33         case .lora: return "lora"
34         case .raleway: return "raleway"
35         }
36     }
37 }
38
39 public enum SliderType: Int{
40     case font
41     case margin
42     case interline
43     
44     var paramText: String{
45         switch self {
46         case .font:
47             return "text"
48         case .margin:
49             return "margin"
50         case .interline:
51             return "interline"
52         }
53     }
54     
55     var leftImage: UIImage{
56         switch self {
57         case .font:
58             return #imageLiteral(resourceName: "reader_font-small")
59         case .margin:
60             return #imageLiteral(resourceName: "reader_margin-small")
61         case .interline:
62             return #imageLiteral(resourceName: "reader_leading-small")
63         }
64     }
65     
66     var rightImage: UIImage{
67         switch self {
68         case .font:
69             return #imageLiteral(resourceName: "reader_font-big")
70         case .margin:
71             return #imageLiteral(resourceName: "reader_margin-big")
72         case .interline:
73             return #imageLiteral(resourceName: "reader_leading-big")
74         }
75     }
76 }
77
78 public enum FolioReaderSliderParamSize: Int {
79     case xs = 0
80     case s
81     case m
82     case l
83     case xl
84
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
94         default: break
95         }
96         return paramSize
97     }
98
99     public func cssIdentifier(sliderType: SliderType) -> String {
100         let paramText = sliderType.paramText
101         switch self {
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"
107         }
108     }
109 }
110
111 class FolioReaderFontsMenu: UIViewController, SMSegmentViewDelegate, UIGestureRecognizerDelegate {
112     var menuView: UIView!
113
114     fileprivate var readerConfig: FolioReaderConfig
115     fileprivate var folioReader: FolioReader
116
117     init(folioReader: FolioReader, readerConfig: FolioReaderConfig) {
118         self.readerConfig = readerConfig
119         self.folioReader = folioReader
120
121         super.init(nibName: nil, bundle: nil)
122     }
123
124     required init?(coder aDecoder: NSCoder) {
125         fatalError("init(coder:) has not been implemented")
126     }
127
128     override func viewDidLoad() {
129         super.viewDidLoad()
130
131         // Do any additional setup after loading the view.
132         self.view.backgroundColor = UIColor.clear
133
134         // Tap gesture
135         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(FolioReaderFontsMenu.tapGesture))
136         tapGesture.numberOfTapsRequired = 1
137         tapGesture.delegate = self
138         view.addGestureRecognizer(tapGesture)
139
140         // Menu view
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)
154
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")
161
162         let sunNormal = sun?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
163         let moonNormal = moon?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
164
165         let sunSelected = sun?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
166         let moonSelected = moon?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
167
168         // Day night mode
169         let dayNight = SMSegmentView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 55),
170                                      separatorColour: self.readerConfig.nightModeSeparatorColor,
171                                      separatorWidth: 1,
172                                      segmentProperties:  [
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
179             ])
180         dayNight.delegate = self
181         dayNight.tag = 1
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)
186
187
188         // Separator
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)
192
193         // Fonts adjust
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,
196                                      separatorWidth: 0,
197                                      segmentProperties:  [
198                                         keySegmentOnSelectionColour: UIColor.clear,
199                                         keySegmentOffSelectionColour: UIColor.clear,
200                                         keySegmentOnSelectionTextColour: selectedColor,
201                                         keySegmentOffSelectionTextColour: normalColor,
202                                         keyContentVerticalMargin: 17 as AnyObject
203             ])
204         fontName.delegate = self
205         fontName.tag = 2
206
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)
211
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)!
216
217         fontName.selectSegmentAtIndex(self.folioReader.currentFont.rawValue)
218         menuView.addSubview(fontName)
219
220         // Separator 2
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)
224
225         addSlider(sliderType: .font, topY: line2.frame.origin.y, selectedColor: selectedColor)
226         
227         addSlider(sliderType: .margin, topY: line2.frame.origin.y + 57, selectedColor: selectedColor)
228
229         addSlider(sliderType: .interline, topY: line2.frame.origin.y + 114, selectedColor: selectedColor)
230
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)
236 //
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
242 //
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)
248 //
249 //        // Force remove fill color
250 //        slider.layer.sublayers?.forEach({ layer in
251 //            layer.backgroundColor = UIColor.clear.cgColor
252 //        })
253 //
254 //        menuView.addSubview(slider)
255 //
256 //        // Font icons
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)
261 //
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)
266
267         // Only continues if user can change scroll direction
268         guard (self.readerConfig.canChangeScrollDirection == true) else {
269             return
270         }
271
272         // Separator 3
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)
277
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)
284
285         // Layout direction
286         let layoutDirection = SMSegmentView(frame: CGRect(x: 0, y: line3.frame.origin.y, width: view.frame.width, height: 55),
287                                             separatorColour: self.readerConfig.nightModeSeparatorColor,
288                                             separatorWidth: 1,
289                                             segmentProperties:  [
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
296             ])
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)
301
302         var scrollDirection = FolioReaderScrollDirection(rawValue: self.folioReader.currentScrollDirection)
303
304         if scrollDirection == .defaultVertical && self.readerConfig.scrollDirection != .defaultVertical {
305             scrollDirection = self.readerConfig.scrollDirection
306         }
307
308         switch scrollDirection ?? .vertical {
309         case .vertical, .defaultVertical:
310             layoutDirection.selectSegmentAtIndex(FolioReaderScrollDirection.vertical.rawValue)
311         case .horizontal, .horizontalWithVerticalContent:
312             layoutDirection.selectSegmentAtIndex(FolioReaderScrollDirection.horizontal.rawValue)
313         }
314         menuView.addSubview(layoutDirection)
315     }
316     
317     func addSlider(sliderType: SliderType, topY: CGFloat, selectedColor: UIColor){
318         
319         let normalColor = UIColor(white: 0.5, alpha: 0.7)
320         
321         // Font slider size
322         let slider = HADiscreteSlider(frame: CGRect(x: 60, y: topY+2, width: view.frame.width-120, height: 55))
323         slider.tickStyle = ComponentStyle.rounded
324         slider.tickCount = 5
325         slider.tickSize = CGSize(width: 8, height: 8)
326         
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
332         
333         slider.backgroundColor = UIColor.clear
334         slider.tintColor = self.readerConfig.nightModeSeparatorColor
335         slider.minimumValue = 0
336         slider.tag = sliderType.rawValue
337         
338         switch sliderType {
339         case .font:
340             slider.value = CGFloat(self.folioReader.currentFontSize.rawValue)
341         case .margin:
342             slider.value = CGFloat(self.folioReader.currentMarginSize.rawValue)
343         case .interline:
344             slider.value = CGFloat(self.folioReader.currentInterlineSize.rawValue)
345         }
346         
347         slider.addTarget(self, action: #selector(FolioReaderFontsMenu.sliderValueChanged(_:)), for: UIControlEvents.valueChanged)
348         
349         // Force remove fill color
350         slider.layer.sublayers?.forEach({ layer in
351             layer.backgroundColor = UIColor.clear.cgColor
352         })
353         
354         menuView.addSubview(slider)
355         
356         // Font icons
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)
361         
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)
366     }
367     
368     // MARK: - SMSegmentView delegate
369
370     func segmentView(_ segmentView: SMSegmentView, didSelectSegmentAtIndex index: Int) {
371         guard (self.folioReader.readerCenter?.currentPage) != nil else { return }
372
373         if segmentView.tag == 1 {
374
375             self.folioReader.nightMode = Bool(index == 1)
376
377             UIView.animate(withDuration: 0.6, animations: {
378                 self.menuView.backgroundColor = (self.folioReader.nightMode ? self.readerConfig.nightModeBackground : UIColor.white)
379             })
380
381         } else if segmentView.tag == 2 {
382
383             self.folioReader.currentFont = FolioReaderFont(rawValue: index)!
384
385         }  else if segmentView.tag == 3 {
386
387             guard self.folioReader.currentScrollDirection != index else {
388                 return
389             }
390
391             self.folioReader.currentScrollDirection = index
392         }
393     }
394     
395     // MARK: - Font slider changed
396     
397     @objc func sliderValueChanged(_ sender: HADiscreteSlider) {
398         guard
399             (self.folioReader.readerCenter?.currentPage != nil), let sliderType = SliderType(rawValue: sender.tag)
400              else {
401                 return
402         }
403         
404         switch sliderType {
405         case .font:
406             if let fontSize = FolioReaderSliderParamSize(rawValue: Int(sender.value)){
407                 self.folioReader.currentFontSize = fontSize
408             }
409         case .margin:
410             if let marginSize = FolioReaderSliderParamSize(rawValue: Int(sender.value)){
411                 self.folioReader.currentMarginSize = marginSize
412             }
413         case .interline:
414             if let interlineSize = FolioReaderSliderParamSize(rawValue: Int(sender.value)){
415                 self.folioReader.currentInterlineSize = interlineSize
416             }
417         }
418     }
419     
420     // MARK: - Gestures
421     
422     @objc func tapGesture() {
423         dismiss()
424         
425         if (self.readerConfig.shouldHideNavigationOnTap == false) {
426             self.folioReader.readerCenter?.showBars()
427         }
428     }
429     
430     func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
431         if gestureRecognizer is UITapGestureRecognizer && touch.view == view {
432             return true
433         }
434         return false
435     }
436     
437     // MARK: - Status Bar
438     
439     override var prefersStatusBarHidden : Bool {
440         return (self.readerConfig.shouldHideNavigationOnTap == true)
441     }
442 }