spiegel-keyman/ios/engine/KMEI/KeymanEngine/Classes/KeyPreviewView.swift
2019-07-01 12:41:15 +10:00

185 lines
6.8 KiB
Swift

//
// 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 Manager.shared.isSystemKeyboard {
isPortrait = InputViewController.isPortrait
} else {
isPortrait = UIDevice.current.orientation.isPortrait
}
keyFrame = frame
let viewWidth = keyFrame.width * (isPortrait ? 1.6 : 1.3)
let viewHeight = keyFrame.size.height * 2.1
var viewPosX = keyFrame.origin.x - (viewWidth - keyFrame.width) / 2.0
let viewPosY = keyFrame.origin.y - (viewHeight - keyFrame.height)
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
}
}
}
}