added iOS source code
[wl-app.git] / iOS / Pods / FolioReaderKit / Source / FolioReaderPlayerMenu.swift
1 //
2 //  FolioReaderFontsMenu.swift
3 //  FolioReaderKit
4 //
5 //  Created by Kevin Jantzer on 1/6/16.
6 //  Copyright (c) 2016 Folio Reader. All rights reserved.
7 //
8
9 import UIKit
10
11 class FolioReaderPlayerMenu: UIViewController, SMSegmentViewDelegate, UIGestureRecognizerDelegate {
12
13     var menuView: UIView!
14     var playPauseBtn: UIButton!
15     var styleOptionBtns = [UIButton]()
16     var viewDidAppear = false
17
18     fileprivate var readerConfig: FolioReaderConfig
19     fileprivate var folioReader: FolioReader
20
21     init(folioReader: FolioReader, readerConfig: FolioReaderConfig) {
22         self.readerConfig = readerConfig
23         self.folioReader = folioReader
24
25         super.init(nibName: nil, bundle: nil)
26     }
27
28     required init?(coder aDecoder: NSCoder) {
29         fatalError("init(coder:) has not been implemented")
30     }
31
32     override func viewDidLoad() {
33         super.viewDidLoad()
34
35         // Do any additional setup after loading the view.
36         self.view.backgroundColor = UIColor.clear
37
38         // Tap gesture
39         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(FolioReaderPlayerMenu.tapGesture))
40         tapGesture.numberOfTapsRequired = 1
41         tapGesture.delegate = self
42         view.addGestureRecognizer(tapGesture)
43
44         // Menu view
45         menuView = UIView(frame: CGRect(x: 0, y: view.frame.height-165, width: view.frame.width, height: view.frame.height))
46         menuView.backgroundColor = self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white)
47         menuView.autoresizingMask = .flexibleWidth
48         menuView.layer.shadowColor = UIColor.black.cgColor
49         menuView.layer.shadowOffset = CGSize(width: 0, height: 0)
50         menuView.layer.shadowOpacity = 0.3
51         menuView.layer.shadowRadius = 6
52         menuView.layer.shadowPath = UIBezierPath(rect: menuView.bounds).cgPath
53         menuView.layer.rasterizationScale = UIScreen.main.scale
54         menuView.layer.shouldRasterize = true
55         view.addSubview(menuView)
56
57         let normalColor = UIColor(white: 0.5, alpha: 0.7)
58         let selectedColor = self.readerConfig.tintColor
59         let size = 55
60         let padX = 32
61         // @NOTE: could this be improved/simplified with autolayout?
62         let gutterX = (Int(view.frame.width) - (size * 3 ) - (padX * 4) ) / 2
63
64         //let btnX = (Int(view.frame.width) - (size * 3)) / 4
65
66         // get icon images
67         let play = UIImage(readerImageNamed: "play-icon")
68         let pause = UIImage(readerImageNamed: "pause-icon")
69         let prev = UIImage(readerImageNamed: "prev-icon")
70         let next = UIImage(readerImageNamed: "next-icon")
71         let playSelected = play?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
72         let pauseSelected = pause?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
73
74         let prevNormal = prev?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
75         let nextNormal = next?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal)
76         let prevSelected = prev?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
77         let nextSelected = next?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal)
78
79         // prev button
80         let prevBtn = UIButton(frame: CGRect(x: gutterX + padX, y: 0, width: size, height: size))
81         prevBtn.setImage(prevNormal, for: UIControlState())
82         prevBtn.setImage(prevSelected, for: .selected)
83         prevBtn.addTarget(self, action: #selector(FolioReaderPlayerMenu.prevChapter(_:)), for: .touchUpInside)
84         menuView.addSubview(prevBtn)
85
86         // play / pause button
87         let playPauseBtn = UIButton(frame: CGRect(x: Int(prevBtn.frame.origin.x) + padX + size, y: 0, width: size, height: size))
88         playPauseBtn.setTitleColor(selectedColor, for: UIControlState())
89         playPauseBtn.setTitleColor(selectedColor, for: .selected)
90         playPauseBtn.setImage(playSelected, for: UIControlState())
91         playPauseBtn.setImage(pauseSelected, for: .selected)
92         playPauseBtn.titleLabel!.font = UIFont(name: "Avenir", size: 22)!
93         playPauseBtn.addTarget(self, action: #selector(FolioReaderPlayerMenu.togglePlay(_:)), for: .touchUpInside)
94         menuView.addSubview(playPauseBtn)
95
96         if let audioPlayer = self.folioReader.readerAudioPlayer , audioPlayer.isPlaying() {
97             playPauseBtn.isSelected = true
98         }
99
100         // next button
101         let nextBtn = UIButton(frame: CGRect(x: Int(playPauseBtn.frame.origin.x) + padX + size, y: 0, width: size, height: size))
102         nextBtn.setImage(nextNormal, for: UIControlState())
103         nextBtn.setImage(nextSelected, for: .selected)
104         nextBtn.addTarget(self, action: #selector(FolioReaderPlayerMenu.nextChapter(_:)), for: .touchUpInside)
105         menuView.addSubview(nextBtn)
106
107
108         // Separator
109         let line = UIView(frame: CGRect(x: 0, y: playPauseBtn.frame.height+playPauseBtn.frame.origin.y, width: view.frame.width, height: 1))
110         line.backgroundColor = self.readerConfig.nightModeSeparatorColor
111         menuView.addSubview(line)
112
113         // audio playback rate adjust
114         let playbackRate = SMSegmentView(frame: CGRect(x: 15, y: line.frame.height+line.frame.origin.y, width: view.frame.width-30, height: 55),
115                                          separatorColour: UIColor.clear,
116                                          separatorWidth: 0,
117                                          segmentProperties:  [
118                                             keySegmentOnSelectionColour: UIColor.clear,
119                                             keySegmentOffSelectionColour: UIColor.clear,
120                                             keySegmentOnSelectionTextColour: selectedColor,
121                                             keySegmentOffSelectionTextColour: normalColor,
122                                             keyContentVerticalMargin: 17 as AnyObject
123             ])
124         playbackRate.delegate = self
125         playbackRate.tag = 2
126         playbackRate.addSegmentWithTitle("½x", onSelectionImage: nil, offSelectionImage: nil)
127         playbackRate.addSegmentWithTitle("1x", onSelectionImage: nil, offSelectionImage: nil)
128         playbackRate.addSegmentWithTitle("1½x", onSelectionImage: nil, offSelectionImage: nil)
129         playbackRate.addSegmentWithTitle("2x", onSelectionImage: nil, offSelectionImage: nil)
130         playbackRate.segmentTitleFont = UIFont(name: "Avenir-Light", size: 17)!
131         playbackRate.selectSegmentAtIndex(Int(self.folioReader.currentAudioRate))
132         menuView.addSubview(playbackRate)
133
134
135         // Separator
136         let line2 = UIView(frame: CGRect(x: 0, y: playbackRate.frame.height+playbackRate.frame.origin.y, width: view.frame.width, height: 1))
137         line2.backgroundColor = self.readerConfig.nightModeSeparatorColor
138         menuView.addSubview(line2)
139
140
141         // Media overlay highlight styles
142         let style0 = UIButton(frame: CGRect(x: 0, y: line2.frame.height+line2.frame.origin.y, width: view.frame.width/3, height: 55))
143         style0.titleLabel!.textAlignment = .center
144         style0.titleLabel!.font = UIFont(name: "Avenir-Light", size: 17)
145         style0.setTitleColor(self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white), for: UIControlState())
146         style0.setTitleColor(self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white), for: .selected)
147         style0.setTitle(self.readerConfig.localizedPlayerMenuStyle, for: UIControlState())
148         menuView.addSubview(style0);
149         style0.titleLabel?.sizeToFit()
150         let style0Bgd = UIView(frame: style0.titleLabel!.frame)
151         style0Bgd.center = CGPoint(x: style0.frame.size.width  / 2, y: style0.frame.size.height / 2);
152         style0Bgd.frame.size.width += 8
153         style0Bgd.frame.origin.x -= 4
154         style0Bgd.backgroundColor = normalColor;
155         style0Bgd.layer.cornerRadius = 3.0;
156         style0Bgd.isUserInteractionEnabled = false
157         style0.insertSubview(style0Bgd, belowSubview: style0.titleLabel!)
158
159         let style1 = UIButton(frame: CGRect(x: view.frame.width/3, y: line2.frame.height+line2.frame.origin.y, width: view.frame.width/3, height: 55))
160         style1.titleLabel!.textAlignment = .center
161         style1.titleLabel!.font = UIFont(name: "Avenir-Light", size: 17)
162         style1.setTitleColor(normalColor, for: UIControlState())
163         style1.setAttributedTitle(NSAttributedString(string: "Style", attributes: [
164             NSAttributedStringKey.foregroundColor: normalColor,
165             NSAttributedStringKey.underlineStyle: NSUnderlineStyle.patternDot.rawValue|NSUnderlineStyle.styleSingle.rawValue,
166             NSAttributedStringKey.underlineColor: normalColor
167             ]), for: UIControlState())
168         style1.setAttributedTitle(NSAttributedString(string: self.readerConfig.localizedPlayerMenuStyle, attributes: [
169             NSAttributedStringKey.foregroundColor: self.folioReader.isNight(UIColor.white, UIColor.black),
170             NSAttributedStringKey.underlineStyle: NSUnderlineStyle.patternDot.rawValue|NSUnderlineStyle.styleSingle.rawValue,
171             NSAttributedStringKey.underlineColor: selectedColor
172             ]), for: .selected)
173         menuView.addSubview(style1);
174
175         let style2 = UIButton(frame: CGRect(x: view.frame.width/1.5, y: line2.frame.height+line2.frame.origin.y, width: view.frame.width/3, height: 55))
176         style2.titleLabel!.textAlignment = .center
177         style2.titleLabel!.font = UIFont(name: "Avenir-Light", size: 17)
178         style2.setTitleColor(normalColor, for: UIControlState())
179         style2.setTitleColor(selectedColor, for: .selected)
180         style2.setTitle(self.readerConfig.localizedPlayerMenuStyle, for: UIControlState())
181         menuView.addSubview(style2);
182
183         // add line dividers between style buttons
184         let style1line = UIView(frame: CGRect(x: style1.frame.origin.x, y: style1.frame.origin.y, width: 1, height: style1.frame.height))
185         style1line.backgroundColor = self.readerConfig.nightModeSeparatorColor
186         menuView.addSubview(style1line)
187         let style2line = UIView(frame: CGRect(x: style2.frame.origin.x, y: style2.frame.origin.y, width: 1, height: style2.frame.height))
188         style2line.backgroundColor = self.readerConfig.nightModeSeparatorColor
189         menuView.addSubview(style2line)
190
191         // select the current style
192         style0.isSelected = (self.folioReader.currentMediaOverlayStyle == .default)
193         style1.isSelected = (self.folioReader.currentMediaOverlayStyle == .underline)
194         style2.isSelected = (self.folioReader.currentMediaOverlayStyle == .textColor)
195         if style0.isSelected { style0Bgd.backgroundColor = selectedColor }
196
197         // hook up button actions
198         style0.tag = MediaOverlayStyle.default.rawValue
199         style1.tag = MediaOverlayStyle.underline.rawValue
200         style2.tag = MediaOverlayStyle.textColor.rawValue
201         style0.addTarget(self, action: #selector(FolioReaderPlayerMenu.changeStyle(_:)), for: .touchUpInside)
202         style1.addTarget(self, action: #selector(FolioReaderPlayerMenu.changeStyle(_:)), for: .touchUpInside)
203         style2.addTarget(self, action: #selector(FolioReaderPlayerMenu.changeStyle(_:)), for: .touchUpInside)
204
205         // store ref to buttons
206         styleOptionBtns.append(style0)
207         styleOptionBtns.append(style1)
208         styleOptionBtns.append(style2)
209     }
210
211
212     override func viewDidAppear(_ animated: Bool) {
213         viewDidAppear = true
214     }
215
216     override func viewDidDisappear(_ animated: Bool) {
217         viewDidAppear = false
218     }
219
220     override func didReceiveMemoryWarning() {
221         super.didReceiveMemoryWarning()
222         // Dispose of any resources that can be recreated.
223     }
224
225     // MARK: - Status Bar
226
227     override var prefersStatusBarHidden : Bool {
228         return (self.readerConfig.shouldHideNavigationOnTap == true)
229     }
230
231     // MARK: - SMSegmentView delegate
232
233     func segmentView(_ segmentView: SMSegmentView, didSelectSegmentAtIndex index: Int) {
234         guard viewDidAppear else { return }
235
236         if let audioPlayer = self.folioReader.readerAudioPlayer, (segmentView.tag == 2) {
237             audioPlayer.setRate(index)
238             self.folioReader.currentAudioRate = index
239         }
240     }
241
242     @objc func prevChapter(_ sender: UIButton!) {
243         self.folioReader.readerAudioPlayer?.playPrevChapter()
244     }
245
246     @objc func nextChapter(_ sender: UIButton!) {
247         self.folioReader.readerAudioPlayer?.playNextChapter()
248     }
249
250     @objc func togglePlay(_ sender: UIButton!) {
251         sender.isSelected = sender.isSelected != true
252         self.folioReader.readerAudioPlayer?.togglePlay()
253         closeView()
254     }
255
256     @objc func changeStyle(_ sender: UIButton!) {
257         self.folioReader.currentMediaOverlayStyle = MediaOverlayStyle(rawValue: sender.tag)!
258
259         // select the proper style button
260         for btn in styleOptionBtns {
261             btn.isSelected = btn == sender
262
263             if btn.tag == MediaOverlayStyle.default.rawValue {
264                 btn.subviews.first?.backgroundColor = (btn.isSelected ? self.readerConfig.tintColor : UIColor(white: 0.5, alpha: 0.7))
265             }
266         }
267
268         // update the current page style
269         if let currentPage = self.folioReader.readerCenter?.currentPage {
270             currentPage.webView?.js("setMediaOverlayStyle(\"\(self.folioReader.currentMediaOverlayStyle.className())\")")
271         }
272     }
273
274     func closeView() {
275         self.dismiss()
276
277         if (self.readerConfig.shouldHideNavigationOnTap == false) {
278             self.folioReader.readerCenter?.showBars()
279         }
280     }
281     
282     // MARK: - Gestures
283     
284     @objc func tapGesture() {
285         closeView()
286     }
287     
288     
289     func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
290         if gestureRecognizer is UITapGestureRecognizer && touch.view == view {
291             return true
292         }
293         return false
294     }
295 }