// // KeyPreviewView.swift // KeymanEngine // // Created by Gabriel Wong on 2017-10-05. // Copyright © 2017 SIL International. All rights reserved. // import UIKit class KeyPreviewView: UIView { private let keyFrame: CGRect private let strokeWidth: CGFloat = 1.0 private let borderRadius: CGFloat = 5.0 private let adjX: CGFloat private let adjY: CGFloat private let borderColor = UIColor(red: 145.0 / 255.0, green: 148.0 / 255.0, blue: 152.0 / 255.0, alpha: 1.0) private var bgColor = UIColor.white private let bgColor2 = UIColor.white private let label: UILabel override init(frame: CGRect) { let isPortrait: Bool if Util.isSystemKeyboard { isPortrait = InputViewController.isPortrait } else { isPortrait = UIDevice.current.orientation.isPortrait } keyFrame = frame let viewWidth = keyFrame.width * (isPortrait ? 1.6 : 1.3) var viewHeight = keyFrame.size.height * 2.1 var viewPosX = keyFrame.origin.x - (viewWidth - keyFrame.width) / 2.0 var viewPosY = keyFrame.origin.y - (viewHeight - keyFrame.height) let tbHeight = Manager.shared.isSystemKeyboardTopBarEnabled ? CGFloat(InputViewController.topBarHeight) : 0 if Util.isSystemKeyboard && (viewPosY < -tbHeight) { adjY = viewPosY + tbHeight viewPosY = CGFloat(-tbHeight) viewHeight += adjY } else { adjY = 0 } if viewPosX < 0 { adjX = keyFrame.origin.x - viewPosX viewPosX = keyFrame.origin.x } else if (viewPosX + viewWidth) > UIScreen.main.bounds.width { adjX = viewPosX - keyFrame.origin.x viewPosX = keyFrame.origin.x + 2 * adjX } else { adjX = 0 } let m = strokeWidth * 2 let fontSize = viewHeight * 0.35 let labelFrame = CGRect(x: m, y: m, width: viewWidth - 2 * m, height: viewHeight * 0.5 - m) label = UILabel(frame: labelFrame) label.numberOfLines = 1 label.minimumScaleFactor = 0.25 label.adjustsFontSizeToFitWidth = true label.textAlignment = .center label.font = UIFont.systemFont(ofSize: fontSize) label.shadowColor = UIColor.lightText label.shadowOffset = CGSize(width: 1.0, height: 1.0) label.backgroundColor = UIColor.clear label.textColor = UIColor.darkText label.text = "" super.init(frame: CGRect(x: viewPosX, y: viewPosY, width: viewWidth, height: viewHeight)) super.backgroundColor = UIColor.clear isUserInteractionEnabled = false addSubview(label) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func draw(_ rect: CGRect) { drawKeyPreviewUp(rect) } private func drawKeyPreviewUp(_ rect: CGRect) { let keyWidth = keyFrame.width let viewWidth = rect.width let viewHeight = rect.height guard let context = UIGraphicsGetCurrentContext() else { return } UIGraphicsPushContext(context) context.setLineJoin(.round) context.setLineWidth(strokeWidth * 2) context.setStrokeColor(borderColor.cgColor) context.setFillColor(bgColor.cgColor) let keyLeft = (viewWidth - keyWidth) / 2.0 + strokeWidth - adjX let keyRight = (viewWidth - keyWidth) / 2.0 + keyWidth - strokeWidth - adjX let midY1 = viewHeight * 3.0 / 5.0 let midY2 = viewHeight / 2.0 let viewLeft = strokeWidth let viewRight = viewWidth - strokeWidth let viewTop = strokeWidth let viewBottom = viewHeight - strokeWidth * 1.25 let viewMid: CGFloat = viewWidth / 2.0 let r0 = borderRadius - strokeWidth let r1 = borderRadius - strokeWidth let r2 = borderRadius * 1.25 - strokeWidth context.beginPath() context.move(to: CGPoint(x: viewMid, y: viewTop)) context.addArc(tangent1End: CGPoint(x: viewLeft, y: viewTop), tangent2End: CGPoint(x: viewLeft, y: midY2), radius: r1) context.addArc(tangent1End: CGPoint(x: viewLeft, y: midY2), tangent2End: CGPoint(x: keyLeft, y: midY1), radius: r2) context.addArc(tangent1End: CGPoint(x: keyLeft, y: midY1), tangent2End: CGPoint(x: keyLeft, y: viewBottom), radius: r2) context.addArc(tangent1End: CGPoint(x: keyLeft, y: viewBottom), tangent2End: CGPoint(x: keyRight, y: viewBottom), radius: r0) context.addArc(tangent1End: CGPoint(x: keyRight, y: viewBottom), tangent2End: CGPoint(x: keyRight, y: midY1), radius: r0) context.addArc(tangent1End: CGPoint(x: keyRight, y: midY1), tangent2End: CGPoint(x: viewRight, y: midY2), radius: r2) context.addArc(tangent1End: CGPoint(x: viewRight, y: midY2), tangent2End: CGPoint(x: viewRight, y: viewTop), radius: r2) context.addArc(tangent1End: CGPoint(x: viewRight, y: viewTop), tangent2End: CGPoint(x: viewMid, y: viewTop), radius: r1) context.closePath() context.drawPath(using: .stroke) context.beginPath() context.move(to: CGPoint(x: viewMid, y: viewTop)) context.addArc(tangent1End: CGPoint(x: viewLeft, y: viewTop), tangent2End: CGPoint(x: viewLeft, y: midY2), radius: r1) context.addArc(tangent1End: CGPoint(x: viewLeft, y: midY2), tangent2End: CGPoint(x: keyLeft, y: midY1), radius: r2) context.addArc(tangent1End: CGPoint(x: keyLeft, y: midY1), tangent2End: CGPoint(x: keyLeft, y: viewBottom), radius: r2) context.addArc(tangent1End: CGPoint(x: keyLeft, y: viewBottom), tangent2End: CGPoint(x: keyRight, y: viewBottom), radius: r0) context.addArc(tangent1End: CGPoint(x: keyRight, y: viewBottom), tangent2End: CGPoint(x: keyRight, y: midY1), radius: r0) context.addArc(tangent1End: CGPoint(x: keyRight, y: midY1), tangent2End: CGPoint(x: viewRight, y: midY2), radius: r2) context.addArc(tangent1End: CGPoint(x: viewRight, y: midY2), tangent2End: CGPoint(x: viewRight, y: viewTop), radius: r2) context.addArc(tangent1End: CGPoint(x: viewRight, y: viewTop), tangent2End: CGPoint(x: viewMid, y: viewTop), radius: r1) context.closePath() context.clip() let colorSpace = CGColorSpaceCreateDeviceRGB() let gradientColors = [bgColor.cgColor, bgColor2.cgColor] as CFArray let gradientLocations: [CGFloat] = [0, 1] let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: gradientLocations)! let startPoint = CGPoint(x: rect.midX, y: rect.minY) let endPoint = CGPoint(x: rect.midX, y: rect.maxY) context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: []) UIGraphicsPopContext() } func setLabelText(_ text: String) { label.text = text } func setLabelFont(_ fontName: String?) { let fontSize = label.font.pointSize if let fontName = fontName { label.font = UIFont(name: fontName, size: fontSize) } else { label.font = UIFont.systemFont(ofSize: fontSize) } } override var backgroundColor: UIColor? { get { return super.backgroundColor } set(color) { super.backgroundColor = UIColor.clear if let color = color { bgColor = color } } } }