1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-11 13:15:35 +03:00

first success build

This commit is contained in:
manindaniil 2017-08-11 15:08:31 +07:00
parent 536bc08709
commit ce1fce6998
16 changed files with 290 additions and 43 deletions

View File

@ -2,8 +2,11 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
let animationProducer = AnimationProducer()
class AnimationProducer {
@ -78,18 +81,22 @@ class AnimationProducer {
return
}
guard let layer = macawView.mLayer else {
return
}
switch animation.type {
case .unknown:
return
case .affineTransformation:
addTransformAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
addTransformAnimation(animation, sceneLayer: layer, animationCache: cache, completion: {
if let next = animation.next {
self.addAnimation(next)
}
})
case .opacity:
addOpacityAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
addOpacityAnimation(animation, sceneLayer: layer, animationCache: cache, completion: {
if let next = animation.next {
self.addAnimation(next)
}
@ -105,13 +112,13 @@ class AnimationProducer {
}
})
case .morphing:
addMorphingAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
addMorphingAnimation(animation, sceneLayer: layer, animationCache: cache, completion: {
if let next = animation.next {
self.addAnimation(next)
}
})
case .shape:
addShapeAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
addShapeAnimation(animation, sceneLayer: layer, animationCache: cache, completion: {
if let next = animation.next {
self.addAnimation(next)
}
@ -320,9 +327,9 @@ class AnimationProducer {
contentsAnimations.append(animationDesc)
if displayLink == .none {
displayLink = CADisplayLink(target: self, selector: #selector(updateContentAnimations))
displayLink?.frameInterval = 1
if displayLink == nil {
displayLink = MDisplayLink(target: self, selector: #selector(updateContentAnimations))
//displayLink?.frameInterval = 1
displayLink?.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
}
}

View File

@ -90,7 +90,9 @@ class AnimationCache {
}
private func calculateAnimationScale(animation: Animation) -> CGFloat {
let defaultScale = UIScreen.main.scale
guard let defaultScale = MMainScreen()?.mScale else {
return 1.0
}
guard let transformAnimation = animation as? TransformAnimation else {
return defaultScale

View File

@ -9,8 +9,11 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
func addMorphingAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> ())) {
guard let morphingAnimation = animation as? MorphingAnimation else {
return

View File

@ -2,8 +2,11 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
func addOpacityAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> ())) {
guard let opacityAnimation = animation as? OpacityAnimation else {
return

View File

@ -9,8 +9,11 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
func addShapeAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> ())) {
guard let shapeAnimation = animation as? ShapeAnimation else {
return

View File

@ -2,6 +2,8 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
func caTimingFunction(_ easing: Easing) -> CAMediaTimingFunction {

View File

@ -2,8 +2,11 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
func addTransformAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> ())) {
guard let transformAnimation = animation as? TransformAnimation else {
return

View File

@ -2,8 +2,11 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
open class Text: Node {
open let textVar: Variable<String>
@ -64,7 +67,7 @@ open class Text: Node {
font = MFont.systemFont(ofSize: CGFloat(f.size))
}
} else {
font = MFont.systemFont(ofSize: MFont.systemFontSize)
font = MFont.systemFont(ofSize: MFont.mSystemFontSize)
}
var stringAttributes: [String: AnyObject] = [:]
stringAttributes[NSFontAttributeName] = font

View File

@ -128,9 +128,9 @@ class NodeRenderer {
return
}
UIGraphicsPushContext(context)
MGraphicsPushContext(context)
defer {
UIGraphicsPopContext()
MGraphicsPopContext()
}
if let rect = clip as? Rect {

View File

@ -2,6 +2,8 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
class RenderUtils {
@ -122,22 +124,22 @@ class RenderUtils {
return toBezierPath(locus).reversing().cgPath
}
class func toBezierPath(_ locus: Locus) -> UIBezierPath {
class func toBezierPath(_ locus: Locus) -> MBezierPath {
if let round = locus as? RoundRect {
let corners = CGSize(width: CGFloat(round.rx), height: CGFloat(round.ry))
return UIBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners:
UIRectCorner.allCorners, cornerRadii: corners)
return MBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners:
MRectCorner.allCorners, cornerRadii: corners)
} else if let arc = locus as? Arc {
if arc.ellipse.rx == arc.ellipse.ry {
return arcToPath(arc)
}
} else if let point = locus as? Point {
let path = UIBezierPath()
let path = MBezierPath()
path.move(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
path.addLine(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
return path
} else if let line = locus as? Line {
let path = UIBezierPath()
let path = MBezierPath()
path.move(to: CGPoint(x: CGFloat(line.x1), y: CGFloat(line.y1)))
path.addLine(to: CGPoint(x: CGFloat(line.x2), y: CGFloat(line.y2)))
return path
@ -148,26 +150,26 @@ class RenderUtils {
} else if let polygon = locus as? Polyline {
return pointsToPath(polygon.points)
} else if let rect = locus as? Rect {
return UIBezierPath(rect: rect.cgRect())
return MBezierPath(rect: rect.cgRect())
} else if let circle = locus as? Circle {
return UIBezierPath(ovalIn: circle.bounds().cgRect())
return MBezierPath(ovalIn: circle.bounds().cgRect())
} else if let path = locus as? Path {
return toBezierPath(path)
}
fatalError("Unsupported locus: \(locus)")
}
fileprivate class func arcToPath(_ arc: Arc) -> UIBezierPath {
fileprivate class func arcToPath(_ arc: Arc) -> MBezierPath {
let shift = CGFloat(arc.shift)
let end = shift + CGFloat(arc.extent)
let ellipse = arc.ellipse
let center = CGPoint(x: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
return UIBezierPath(arcCenter: center, radius: CGFloat(ellipse.rx), startAngle: shift, endAngle: end, clockwise: true)
return MBezierPath(arcCenter: center, radius: CGFloat(ellipse.rx), startAngle: shift, endAngle: end, clockwise: true)
}
fileprivate class func pointsToPath(_ points: [Double]) -> UIBezierPath {
fileprivate class func pointsToPath(_ points: [Double]) -> MBezierPath {
let parts = stride(from: 0, to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) }
let path = UIBezierPath()
let path = MBezierPath()
var first = true
for part in parts {
let point = CGPoint(x: CGFloat(part[0]), y: CGFloat(part[1]))
@ -181,8 +183,8 @@ class RenderUtils {
return path
}
fileprivate class func toBezierPath(_ path: Path) -> UIBezierPath {
let bezierPath = UIBezierPath()
fileprivate class func toBezierPath(_ path: Path) -> MBezierPath {
let bezierPath = MBezierPath()
var currentPoint: CGPoint?
var cubicPoint: CGPoint?

View File

@ -2,6 +2,8 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
class ShapeRenderer: NodeRenderer {
@ -83,8 +85,8 @@ class ShapeRenderer: NodeRenderer {
ctx.addRect(newCGRect(rect))
} else if let round = locus as? RoundRect {
let corners = CGSize(width: CGFloat(round.rx), height: CGFloat(round.ry))
let path = UIBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners:
UIRectCorner.allCorners, cornerRadii: corners).cgPath
let path = MBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners:
MRectCorner.allCorners, cornerRadii: corners).cgPath
ctx.addPath(path)
} else if let circle = locus as? Circle {
let cx = circle.cx
@ -102,17 +104,17 @@ class ShapeRenderer: NodeRenderer {
}
}
fileprivate func toBezierPath(_ arc: Arc) -> UIBezierPath {
fileprivate func toBezierPath(_ arc: Arc) -> MBezierPath {
let shift = CGFloat(arc.shift)
let end = shift + CGFloat(arc.extent)
let ellipse = arc.ellipse
let center = CGPoint(x: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
return UIBezierPath(arcCenter: center, radius: CGFloat(ellipse.rx), startAngle: shift, endAngle: end, clockwise: true)
return MBezierPath(arcCenter: center, radius: CGFloat(ellipse.rx), startAngle: shift, endAngle: end, clockwise: true)
}
fileprivate func toBezierPath(_ points: [Double]) -> UIBezierPath {
fileprivate func toBezierPath(_ points: [Double]) -> MBezierPath {
let parts = stride(from: 0, to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) }
let path = UIBezierPath()
let path = MBezierPath()
var first = true
for part in parts {
let point = CGPoint(x: CGFloat(part[0]), y: CGFloat(part[1]))
@ -126,8 +128,8 @@ class ShapeRenderer: NodeRenderer {
return path
}
fileprivate func toBezierPath(_ path: Path) -> UIBezierPath {
let bezierPath = UIBezierPath()
fileprivate func toBezierPath(_ path: Path) -> MBezierPath {
let bezierPath = MBezierPath()
var currentPoint: CGPoint?
var cubicPoint: CGPoint?

View File

@ -1,8 +1,9 @@
import Foundation
import CoreGraphics
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
class TextRenderer: NodeRenderer {
@ -73,7 +74,7 @@ class TextRenderer: NodeRenderer {
return MFont.systemFont(ofSize: CGFloat(textFont.size))
}
}
return MFont.systemFont(ofSize: MFont.systemFontSize)
return MFont.systemFont(ofSize: MFont.mSystemFontSize)
}
fileprivate func getBounds(_ font: MFont) -> CGRect {
@ -122,7 +123,13 @@ class TextRenderer: NodeRenderer {
fileprivate func getTextColor(_ fill: Fill) -> MColor {
if let color = fill as? Color {
return MColor(cgColor: RenderUtils.mapColor(color))
#if os(iOS)
return MColor(cgColor: RenderUtils.mapColor(color))
#elseif os(OSX)
return MColor(cgColor: RenderUtils.mapColor(color)) ?? .black
#endif
}
return MColor.black
}

View File

@ -2,6 +2,8 @@ import Foundation
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
open class SVGView: MacawView {
@ -30,7 +32,7 @@ open class SVGView: MacawView {
self.init(node: Group(), coder: aDecoder)
}
open override var contentMode: UIViewContentMode {
open override var contentMode: MViewContentMode {
didSet {
render()
}

View File

@ -11,11 +11,13 @@ import Foundation
#if os(iOS)
import UIKit
public typealias MRectCorner = UIRectCorner
public typealias MFont = UIFont
public typealias MColor = UIColor
public typealias MEvent = UIEvent
public typealias MTouch = UITouch
public typealias MImage = UIImage
public typealias MBezierPath = UIBezierPath
public typealias MGestureRecognizer = UIGestureRecognizer
public typealias MGestureRecognizerState = UIGestureRecognizerState
public typealias MGestureRecognizerDelegate = UIGestureRecognizerDelegate
@ -25,6 +27,7 @@ import Foundation
public typealias MRotationGestureRecognizer = UIRotationGestureRecognizer
public typealias MScreen = UIScreen
public typealias MDisplayLink = CADisplayLink
public typealias MViewContentMode = UIViewContentMode
extension MTapGestureRecognizer {
func mNumberOfTouches() -> Int {
@ -80,6 +83,12 @@ import Foundation
}
}
extension MFont {
class var mSystemFontSize: CGFloat {
return UIFont.systemFontSize
}
}
open class MView: UIView {
var mLayer: CALayer? {
@ -91,19 +100,19 @@ import Foundation
}
open override func touchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
self.mTouchesBegan(touches, withEvent: event)
self.mTouchesBegan(touches, with: event)
}
open override func touchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
self.mTouchesMoved(touches, withEvent: event)
self.mTouchesMoved(touches, with: event)
}
open override func touchesEnded(_ touches: Set<MTouch>, with event: MEvent?) {
self.mTouchesEnded(touches, withEvent: event)
self.mTouchesEnded(touches, with: event)
}
open override func touchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
self.mTouchesCancelled(touches, withEvent: event)
self.mTouchesCancelled(touches, with: event)
}
open func mTouchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {

View File

@ -17,6 +17,7 @@ import Foundation
public typealias MEvent = NSEvent
public typealias MTouch = NSTouch
public typealias MImage = NSImage
public typealias MBezierPath = NSBezierPath
public typealias MGestureRecognizer = NSGestureRecognizer
public typealias MGestureRecognizerState = NSGestureRecognizerState
public typealias MGestureRecognizerDelegate = NSGestureRecognizerDelegate
@ -36,7 +37,6 @@ import Foundation
}
}
extension MTapGestureRecognizer {
func mNumberOfTouches() -> Int {
return 1
@ -95,6 +95,22 @@ import Foundation
}
}
public enum MViewContentMode: Int {
case scaleToFill
case scaleAspectFit
case scaleAspectFill
case redraw
case center
case top
case bottom
case left
case right
case topLeft
case topRight
case bottomLeft
case bottomRight
}
open class MView: NSView {
open override var isFlipped: Bool {
return true
@ -119,6 +135,8 @@ import Foundation
return self.layer
}
var contentMode: MViewContentMode = .scaleToFill
func didMoveToSuperview() {
super.viewDidMoveToSuperview()
}
@ -127,6 +145,10 @@ import Foundation
self.setNeedsDisplay(self.bounds)
}
func layoutSubviews() {
super.resizeSubviews(withOldSize: self.bounds.size)
}
open override func touchesBegan(with event: NSEvent) {
self.mTouchesBegan(event.touches(matching: .any, in: self), with: event)
}
@ -164,6 +186,10 @@ import Foundation
var lineHeight: CGFloat {
return self.boundingRectForFont.size.height
}
class var mSystemFontSize: CGFloat {
return NSFont.systemFontSize()
}
}
extension NSScreen {
@ -179,7 +205,7 @@ import Foundation
}
extension NSTouch {
func locationInView(view: NSView) -> NSPoint {
func location(in view: NSView) -> NSPoint {
let n = self.normalizedPosition
let b = view.bounds
return NSPoint(x: b.origin.x + b.size.width * n.x, y: b.origin.y + b.size.height * n.y)
@ -312,6 +338,10 @@ import Foundation
stop()
}
open func invalidate() {
stop()
}
open func add(to runloop: RunLoop, forMode mode: RunLoopMode) {
if displayLink != nil {
CVDisplayLinkStart(displayLink!)
@ -336,6 +366,176 @@ import Foundation
}
}
public struct MRectCorner: OptionSet {
public let rawValue: UInt
public static let none = MRectCorner(rawValue: 0)
public static let topLeft = MRectCorner(rawValue: 1 << 0)
public static let topRight = MRectCorner(rawValue: 1 << 1)
public static let bottomLeft = MRectCorner(rawValue: 1 << 2)
public static let bottomRight = MRectCorner(rawValue: 1 << 3)
public static var allCorners: MRectCorner {
return [.topLeft, .topRight, .bottomLeft, .bottomRight]
}
public init(rawValue: UInt) {
self.rawValue = rawValue
}
}
extension MBezierPath {
public var cgPath: CGPath {
get { let path = CGMutablePath()
var points = [CGPoint](repeating: .zero, count: 3)
for i in 0 ..< self.elementCount {
let type = self.element(at: i, associatedPoints: &points)
switch type {
case .moveToBezierPathElement:
path.move(to: CGPoint(x: points[0].x, y: points[0].y))
case .lineToBezierPathElement:
path.addLine(to: CGPoint(x: points[0].x, y: points[0].y))
case .curveToBezierPathElement:
path.addCurve(
to: CGPoint(x: points[2].x, y: points[2].y),
control1: CGPoint(x: points[0].x, y: points[0].y),
control2: CGPoint(x: points[1].x, y: points[1].y))
case .closePathBezierPathElement:
path.closeSubpath()
}
}
return path
}
}
public convenience init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) {
self.init()
self.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)
}
public convenience init(roundedRect rect: NSRect, byRoundingCorners corners: MRectCorner, cornerRadii: NSSize) {
self.init()
let topLeft = rect.origin
let topRight = NSPoint(x: rect.maxX, y: rect.minY);
let bottomRight = NSPoint(x: rect.maxX, y: rect.maxY);
let bottomLeft = NSPoint(x: rect.minX, y: rect.maxY);
if corners.contains(.topLeft) {
move(to: CGPoint(
x: topLeft.x + cornerRadii.width,
y: topLeft.y))
} else {
move(to: topLeft)
}
if corners.contains(.topRight) {
line(to: CGPoint(
x: topRight.x - cornerRadii.width,
y: topRight.y))
curve(
to: topRight,
controlPoint1: CGPoint(
x: topRight.x,
y: topRight.y + cornerRadii.height),
controlPoint2: CGPoint(
x: topRight.x,
y: topRight.y + cornerRadii.height))
} else {
line(to: topRight)
}
if corners.contains(.bottomRight) {
line(to: CGPoint(
x: bottomRight.x,
y: bottomRight.y - cornerRadii.height))
curve(
to: bottomRight,
controlPoint1: CGPoint(
x: bottomRight.x - cornerRadii.width,
y: bottomRight.y),
controlPoint2: CGPoint(
x: bottomRight.x - cornerRadii.width,
y: bottomRight.y))
} else {
line(to: bottomRight)
}
if corners.contains(.bottomLeft) {
line(to: CGPoint(
x: bottomLeft.x + cornerRadii.width,
y: bottomLeft.y))
curve(
to: bottomLeft,
controlPoint1: CGPoint(
x: bottomLeft.x,
y: bottomLeft.y - cornerRadii.height),
controlPoint2: CGPoint(
x: bottomLeft.x,
y: bottomLeft.y - cornerRadii.height))
} else {
line(to: bottomLeft)
}
if corners.contains(.topLeft) {
line(to: CGPoint(
x: topLeft.x,
y: topLeft.y + cornerRadii.height))
curve(
to: topLeft,
controlPoint1: CGPoint(
x: topLeft.x + cornerRadii.width,
y: topLeft.y),
controlPoint2: CGPoint(
x: topLeft.x + cornerRadii.width,
y: topLeft.y))
} else {
line(to: topLeft)
}
close()
}
func reversing() -> MBezierPath {
return self.reversed
}
func addLine(to: NSPoint) {
self.line(to: to)
}
func addCurve(to: NSPoint, controlPoint1: NSPoint, controlPoint2: NSPoint) {
self.curve(to: to, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
}
func addQuadCurveToPoint(endPoint: NSPoint, controlPoint: NSPoint) {
let QP0 = self.currentPoint
let CP3 = endPoint
let CP1 = CGPoint(
x: QP0.x + ((2.0 / 3.0) * (controlPoint.x - QP0.x)),
y: QP0.y + ((2.0 / 3.0) * (controlPoint.y - QP0.y))
)
let CP2 = CGPoint(
x: endPoint.x + (2.0 / 3.0) * (controlPoint.x - endPoint.x),
y: endPoint.y + (2.0 / 3.0) * (controlPoint.y - endPoint.y)
)
self.addCurve(to: CP3, controlPoint1: CP1, controlPoint2: CP2)
}
func addArc(withCenter: NSPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) {
let startAngleRadian = ((startAngle) * (180.0 / .pi))
let endAngleRadian = ((endAngle) * (180.0 / .pi))
self.appendArc(withCenter: withCenter, radius: radius, startAngle: startAngleRadian, endAngle: endAngleRadian, clockwise: !clockwise)
}
func addPath(path: NSBezierPath!) {
self.append(path)
}
}
#endif

View File

@ -1,5 +1,4 @@
import Foundation
import CoreGraphics
#if os(iOS)
import UIKit