// // FolioReaderFontsMenu.swift // FolioReaderKit // // Created by Kevin Jantzer on 1/6/16. // Copyright (c) 2016 Folio Reader. All rights reserved. // import UIKit class FolioReaderPlayerMenu: UIViewController, SMSegmentViewDelegate, UIGestureRecognizerDelegate { var menuView: UIView! var playPauseBtn: UIButton! var styleOptionBtns = [UIButton]() var viewDidAppear = false fileprivate var readerConfig: FolioReaderConfig fileprivate var folioReader: FolioReader init(folioReader: FolioReader, readerConfig: FolioReaderConfig) { self.readerConfig = readerConfig self.folioReader = folioReader super.init(nibName: nil, bundle: nil) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. self.view.backgroundColor = UIColor.clear // Tap gesture let tapGesture = UITapGestureRecognizer(target: self, action: #selector(FolioReaderPlayerMenu.tapGesture)) tapGesture.numberOfTapsRequired = 1 tapGesture.delegate = self view.addGestureRecognizer(tapGesture) // Menu view menuView = UIView(frame: CGRect(x: 0, y: view.frame.height-165, width: view.frame.width, height: view.frame.height)) menuView.backgroundColor = self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white) menuView.autoresizingMask = .flexibleWidth menuView.layer.shadowColor = UIColor.black.cgColor menuView.layer.shadowOffset = CGSize(width: 0, height: 0) menuView.layer.shadowOpacity = 0.3 menuView.layer.shadowRadius = 6 menuView.layer.shadowPath = UIBezierPath(rect: menuView.bounds).cgPath menuView.layer.rasterizationScale = UIScreen.main.scale menuView.layer.shouldRasterize = true view.addSubview(menuView) let normalColor = UIColor(white: 0.5, alpha: 0.7) let selectedColor = self.readerConfig.tintColor let size = 55 let padX = 32 // @NOTE: could this be improved/simplified with autolayout? let gutterX = (Int(view.frame.width) - (size * 3 ) - (padX * 4) ) / 2 //let btnX = (Int(view.frame.width) - (size * 3)) / 4 // get icon images let play = UIImage(readerImageNamed: "play-icon") let pause = UIImage(readerImageNamed: "pause-icon") let prev = UIImage(readerImageNamed: "prev-icon") let next = UIImage(readerImageNamed: "next-icon") let playSelected = play?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal) let pauseSelected = pause?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal) let prevNormal = prev?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal) let nextNormal = next?.imageTintColor(normalColor)?.withRenderingMode(.alwaysOriginal) let prevSelected = prev?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal) let nextSelected = next?.imageTintColor(selectedColor)?.withRenderingMode(.alwaysOriginal) // prev button let prevBtn = UIButton(frame: CGRect(x: gutterX + padX, y: 0, width: size, height: size)) prevBtn.setImage(prevNormal, for: UIControlState()) prevBtn.setImage(prevSelected, for: .selected) prevBtn.addTarget(self, action: #selector(FolioReaderPlayerMenu.prevChapter(_:)), for: .touchUpInside) menuView.addSubview(prevBtn) // play / pause button let playPauseBtn = UIButton(frame: CGRect(x: Int(prevBtn.frame.origin.x) + padX + size, y: 0, width: size, height: size)) playPauseBtn.setTitleColor(selectedColor, for: UIControlState()) playPauseBtn.setTitleColor(selectedColor, for: .selected) playPauseBtn.setImage(playSelected, for: UIControlState()) playPauseBtn.setImage(pauseSelected, for: .selected) playPauseBtn.titleLabel!.font = UIFont(name: "Avenir", size: 22)! playPauseBtn.addTarget(self, action: #selector(FolioReaderPlayerMenu.togglePlay(_:)), for: .touchUpInside) menuView.addSubview(playPauseBtn) if let audioPlayer = self.folioReader.readerAudioPlayer , audioPlayer.isPlaying() { playPauseBtn.isSelected = true } // next button let nextBtn = UIButton(frame: CGRect(x: Int(playPauseBtn.frame.origin.x) + padX + size, y: 0, width: size, height: size)) nextBtn.setImage(nextNormal, for: UIControlState()) nextBtn.setImage(nextSelected, for: .selected) nextBtn.addTarget(self, action: #selector(FolioReaderPlayerMenu.nextChapter(_:)), for: .touchUpInside) menuView.addSubview(nextBtn) // Separator let line = UIView(frame: CGRect(x: 0, y: playPauseBtn.frame.height+playPauseBtn.frame.origin.y, width: view.frame.width, height: 1)) line.backgroundColor = self.readerConfig.nightModeSeparatorColor menuView.addSubview(line) // audio playback rate adjust let playbackRate = SMSegmentView(frame: CGRect(x: 15, y: line.frame.height+line.frame.origin.y, width: view.frame.width-30, height: 55), separatorColour: UIColor.clear, separatorWidth: 0, segmentProperties: [ keySegmentOnSelectionColour: UIColor.clear, keySegmentOffSelectionColour: UIColor.clear, keySegmentOnSelectionTextColour: selectedColor, keySegmentOffSelectionTextColour: normalColor, keyContentVerticalMargin: 17 as AnyObject ]) playbackRate.delegate = self playbackRate.tag = 2 playbackRate.addSegmentWithTitle("½x", onSelectionImage: nil, offSelectionImage: nil) playbackRate.addSegmentWithTitle("1x", onSelectionImage: nil, offSelectionImage: nil) playbackRate.addSegmentWithTitle("1½x", onSelectionImage: nil, offSelectionImage: nil) playbackRate.addSegmentWithTitle("2x", onSelectionImage: nil, offSelectionImage: nil) playbackRate.segmentTitleFont = UIFont(name: "Avenir-Light", size: 17)! playbackRate.selectSegmentAtIndex(Int(self.folioReader.currentAudioRate)) menuView.addSubview(playbackRate) // Separator let line2 = UIView(frame: CGRect(x: 0, y: playbackRate.frame.height+playbackRate.frame.origin.y, width: view.frame.width, height: 1)) line2.backgroundColor = self.readerConfig.nightModeSeparatorColor menuView.addSubview(line2) // Media overlay highlight styles let style0 = UIButton(frame: CGRect(x: 0, y: line2.frame.height+line2.frame.origin.y, width: view.frame.width/3, height: 55)) style0.titleLabel!.textAlignment = .center style0.titleLabel!.font = UIFont(name: "Avenir-Light", size: 17) style0.setTitleColor(self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white), for: UIControlState()) style0.setTitleColor(self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white), for: .selected) style0.setTitle(self.readerConfig.localizedPlayerMenuStyle, for: UIControlState()) menuView.addSubview(style0); style0.titleLabel?.sizeToFit() let style0Bgd = UIView(frame: style0.titleLabel!.frame) style0Bgd.center = CGPoint(x: style0.frame.size.width / 2, y: style0.frame.size.height / 2); style0Bgd.frame.size.width += 8 style0Bgd.frame.origin.x -= 4 style0Bgd.backgroundColor = normalColor; style0Bgd.layer.cornerRadius = 3.0; style0Bgd.isUserInteractionEnabled = false style0.insertSubview(style0Bgd, belowSubview: style0.titleLabel!) 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)) style1.titleLabel!.textAlignment = .center style1.titleLabel!.font = UIFont(name: "Avenir-Light", size: 17) style1.setTitleColor(normalColor, for: UIControlState()) style1.setAttributedTitle(NSAttributedString(string: "Style", attributes: [ NSAttributedStringKey.foregroundColor: normalColor, NSAttributedStringKey.underlineStyle: NSUnderlineStyle.patternDot.rawValue|NSUnderlineStyle.styleSingle.rawValue, NSAttributedStringKey.underlineColor: normalColor ]), for: UIControlState()) style1.setAttributedTitle(NSAttributedString(string: self.readerConfig.localizedPlayerMenuStyle, attributes: [ NSAttributedStringKey.foregroundColor: self.folioReader.isNight(UIColor.white, UIColor.black), NSAttributedStringKey.underlineStyle: NSUnderlineStyle.patternDot.rawValue|NSUnderlineStyle.styleSingle.rawValue, NSAttributedStringKey.underlineColor: selectedColor ]), for: .selected) menuView.addSubview(style1); 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)) style2.titleLabel!.textAlignment = .center style2.titleLabel!.font = UIFont(name: "Avenir-Light", size: 17) style2.setTitleColor(normalColor, for: UIControlState()) style2.setTitleColor(selectedColor, for: .selected) style2.setTitle(self.readerConfig.localizedPlayerMenuStyle, for: UIControlState()) menuView.addSubview(style2); // add line dividers between style buttons let style1line = UIView(frame: CGRect(x: style1.frame.origin.x, y: style1.frame.origin.y, width: 1, height: style1.frame.height)) style1line.backgroundColor = self.readerConfig.nightModeSeparatorColor menuView.addSubview(style1line) let style2line = UIView(frame: CGRect(x: style2.frame.origin.x, y: style2.frame.origin.y, width: 1, height: style2.frame.height)) style2line.backgroundColor = self.readerConfig.nightModeSeparatorColor menuView.addSubview(style2line) // select the current style style0.isSelected = (self.folioReader.currentMediaOverlayStyle == .default) style1.isSelected = (self.folioReader.currentMediaOverlayStyle == .underline) style2.isSelected = (self.folioReader.currentMediaOverlayStyle == .textColor) if style0.isSelected { style0Bgd.backgroundColor = selectedColor } // hook up button actions style0.tag = MediaOverlayStyle.default.rawValue style1.tag = MediaOverlayStyle.underline.rawValue style2.tag = MediaOverlayStyle.textColor.rawValue style0.addTarget(self, action: #selector(FolioReaderPlayerMenu.changeStyle(_:)), for: .touchUpInside) style1.addTarget(self, action: #selector(FolioReaderPlayerMenu.changeStyle(_:)), for: .touchUpInside) style2.addTarget(self, action: #selector(FolioReaderPlayerMenu.changeStyle(_:)), for: .touchUpInside) // store ref to buttons styleOptionBtns.append(style0) styleOptionBtns.append(style1) styleOptionBtns.append(style2) } override func viewDidAppear(_ animated: Bool) { viewDidAppear = true } override func viewDidDisappear(_ animated: Bool) { viewDidAppear = false } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - Status Bar override var prefersStatusBarHidden : Bool { return (self.readerConfig.shouldHideNavigationOnTap == true) } // MARK: - SMSegmentView delegate func segmentView(_ segmentView: SMSegmentView, didSelectSegmentAtIndex index: Int) { guard viewDidAppear else { return } if let audioPlayer = self.folioReader.readerAudioPlayer, (segmentView.tag == 2) { audioPlayer.setRate(index) self.folioReader.currentAudioRate = index } } @objc func prevChapter(_ sender: UIButton!) { self.folioReader.readerAudioPlayer?.playPrevChapter() } @objc func nextChapter(_ sender: UIButton!) { self.folioReader.readerAudioPlayer?.playNextChapter() } @objc func togglePlay(_ sender: UIButton!) { sender.isSelected = sender.isSelected != true self.folioReader.readerAudioPlayer?.togglePlay() closeView() } @objc func changeStyle(_ sender: UIButton!) { self.folioReader.currentMediaOverlayStyle = MediaOverlayStyle(rawValue: sender.tag)! // select the proper style button for btn in styleOptionBtns { btn.isSelected = btn == sender if btn.tag == MediaOverlayStyle.default.rawValue { btn.subviews.first?.backgroundColor = (btn.isSelected ? self.readerConfig.tintColor : UIColor(white: 0.5, alpha: 0.7)) } } // update the current page style if let currentPage = self.folioReader.readerCenter?.currentPage { currentPage.webView?.js("setMediaOverlayStyle(\"\(self.folioReader.currentMediaOverlayStyle.className())\")") } } func closeView() { self.dismiss() if (self.readerConfig.shouldHideNavigationOnTap == false) { self.folioReader.readerCenter?.showBars() } } // MARK: - Gestures @objc func tapGesture() { closeView() } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { if gestureRecognizer is UITapGestureRecognizer && touch.view == view { return true } return false } }