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

Raw automated swift 3.0 conversion (not buildable)

This commit is contained in:
Victor Sukochev 2016-09-27 19:45:31 +06:00
parent be9f26903f
commit bed4386799
93 changed files with 1017 additions and 1009 deletions

1
Example/.swift-version Normal file
View File

@ -0,0 +1 @@
3.0

View File

@ -301,7 +301,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0710; LastSwiftUpdateCheck = 0710;
LastUpgradeCheck = 0710; LastUpgradeCheck = 0800;
ORGANIZATIONNAME = Exyte; ORGANIZATIONNAME = Exyte;
TargetAttributes = { TargetAttributes = {
B02E75EC1C16104900D1971D = { B02E75EC1C16104900D1971D = {
@ -474,8 +474,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@ -518,8 +520,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@ -538,6 +542,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.1; IPHONEOS_DEPLOYMENT_TARGET = 9.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
name = Release; name = Release;
@ -546,6 +551,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = B1435E8977BA0B9A49C4E399 /* Pods-Example.debug.xcconfig */; baseConfigurationReference = B1435E8977BA0B9A49C4E399 /* Pods-Example.debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@ -555,7 +561,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example; PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
SWIFT_VERSION = 2.3; SWIFT_VERSION = 3.0;
}; };
name = Debug; name = Debug;
}; };
@ -563,6 +569,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 131DDFA4A9D164CC4B64C3E8 /* Pods-Example.release.xcconfig */; baseConfigurationReference = 131DDFA4A9D164CC4B64C3E8 /* Pods-Example.release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@ -572,7 +579,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example; PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
SWIFT_VERSION = 2.3; SWIFT_VERSION = 3.0;
}; };
name = Release; name = Release;
}; };

View File

@ -14,31 +14,31 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch. // Override point for customization after application launch.
return true return true
} }
func applicationWillResignActive(application: UIApplication) { func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
} }
func applicationDidEnterBackground(application: UIApplication) { func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
} }
func applicationWillEnterForeground(application: UIApplication) { func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
} }
func applicationDidBecomeActive(application: UIApplication) { func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
AnimationRestorer.restore() AnimationRestorer.restore()
} }
func applicationWillTerminate(application: UIApplication) { func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
} }
} }

View File

@ -3,7 +3,7 @@ import Foundation
class BasePageViewController: UIPageViewController { class BasePageViewController: UIPageViewController {
private lazy var orderedViewControllers: [UIViewController] = { fileprivate lazy var orderedViewControllers: [UIViewController] = {
return [ return [
self.newMacawViewController("MenuViewController"), self.newMacawViewController("MenuViewController"),
self.newMacawViewController("FirstPageViewController"), self.newMacawViewController("FirstPageViewController"),
@ -19,9 +19,9 @@ class BasePageViewController: UIPageViewController {
] ]
}() }()
private func newMacawViewController(controllerName: String) -> UIViewController { fileprivate func newMacawViewController(_ controllerName: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) return UIStoryboard(name: "Main", bundle: nil)
.instantiateViewControllerWithIdentifier(controllerName) .instantiateViewController(withIdentifier: controllerName)
} }
override func viewDidLoad() { override func viewDidLoad() {
@ -30,7 +30,7 @@ class BasePageViewController: UIPageViewController {
if let firstViewController = orderedViewControllers.first { if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController], setViewControllers([firstViewController],
direction: .Forward, direction: .forward,
animated: true, animated: true,
completion: nil) completion: nil)
} }
@ -44,9 +44,9 @@ class BasePageViewController: UIPageViewController {
extension BasePageViewController: UIPageViewControllerDataSource { extension BasePageViewController: UIPageViewControllerDataSource {
func pageViewController(pageViewController: UIPageViewController, func pageViewController(_ pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? { viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else { guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil return nil
} }
@ -65,9 +65,9 @@ extension BasePageViewController: UIPageViewControllerDataSource {
return orderedViewControllers[previousIndex] return orderedViewControllers[previousIndex]
} }
func pageViewController(pageViewController: UIPageViewController, func pageViewController(_ pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? { viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else { guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil return nil
} }
@ -87,16 +87,16 @@ extension BasePageViewController: UIPageViewControllerDataSource {
return orderedViewControllers[nextIndex] return orderedViewControllers[nextIndex]
} }
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int { func presentationCount(for pageViewController: UIPageViewController) -> Int {
return orderedViewControllers.count return orderedViewControllers.count
} }
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int { func presentationIndex(for pageViewController: UIPageViewController) -> Int {
guard let firstViewController = viewControllers?.first, guard let firstViewController = viewControllers?.first,
firstViewControllerIndex = orderedViewControllers.indexOf(firstViewController) else { let firstViewControllerIndex = orderedViewControllers.index(of: firstViewController) else {
return 0 return 0
} }
return firstViewControllerIndex return firstViewControllerIndex
} }
} }

View File

@ -4,7 +4,7 @@ class AnimationsExampleController: UIViewController {
var animView: AnimationsView? var animView: AnimationsView?
override func viewDidAppear(animated: Bool) { override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
animView?.prepareAnimation() animView?.prepareAnimation()

View File

@ -30,7 +30,7 @@ class AnimationsView: MacawView {
var velocities = [Point]() var velocities = [Point]()
var positions = [Point]() var positions = [Point]()
func posForTime(t: Double, index: Int) -> Point { func posForTime(_ t: Double, index: Int) -> Point {
let prevPos = positions[index] let prevPos = positions[index]
var velocity = velocities[index] var velocity = velocities[index]

View File

@ -9,20 +9,20 @@ class ModelListenersExampleController: UIViewController {
@IBOutlet weak var widthSteppter: UIStepper! @IBOutlet weak var widthSteppter: UIStepper!
@IBOutlet weak var radiusStepper: UIStepper! @IBOutlet weak var radiusStepper: UIStepper!
@IBAction func onHeightChange(sender: AnyObject) { @IBAction func onHeightChange(_ sender: AnyObject) {
updateForm() updateForm()
} }
@IBAction func onWidthChange(sender: AnyObject) { @IBAction func onWidthChange(_ sender: AnyObject) {
updateForm() updateForm()
} }
@IBAction func onRadiusChange(sender: AnyObject) { @IBAction func onRadiusChange(_ sender: AnyObject) {
updateForm() updateForm()
} }
func updateForm() { func updateForm() {
let screenSize: CGRect = UIScreen.mainScreen().bounds let screenSize: CGRect = UIScreen.main.bounds
let height = heightStepper.value let height = heightStepper.value
let width = widthSteppter.value let width = widthSteppter.value
let radius = radiusStepper.value let radius = radiusStepper.value

View File

@ -7,7 +7,7 @@ class RectShapeView: MacawView {
var rectShape: Shape! var rectShape: Shape!
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
let screenSize: CGRect = UIScreen.mainScreen().bounds let screenSize: CGRect = UIScreen.main.bounds
let rect = RoundRect( let rect = RoundRect(
rect: Rect(x: Double(screenSize.width / 2) - 50, y: Double(screenSize.height / 2) - 50, w: 100, h: 100), rect: Rect(x: Double(screenSize.width / 2) - 50, y: Double(screenSize.height / 2) - 50, w: 100, h: 100),
@ -24,4 +24,4 @@ class RectShapeView: MacawView {
super.init(node: rectShape, coder: aDecoder) super.init(node: rectShape, coder: aDecoder)
} }
} }

View File

@ -4,7 +4,7 @@ class PathExampleController: UIViewController {
var sceneView: PathExampleView? var sceneView: PathExampleView?
@IBOutlet var slider: UISlider? @IBOutlet var slider: UISlider?
override func viewDidAppear(animated: Bool) { override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
sceneView?.testAnimation() sceneView?.testAnimation()
@ -14,7 +14,7 @@ class PathExampleController: UIViewController {
} }
} }
@IBAction func onScaleUpdate(slider: UISlider) { @IBAction func onScaleUpdate(_ slider: UISlider) {
sceneView?.updateScale(slider.value) sceneView?.updateScale(slider.value)
} }
} }

View File

@ -135,17 +135,17 @@ class PathExampleView: MacawView {
} }
func testAnimation() { func testAnimation() {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * NSEC_PER_SEC)), dispatch_get_main_queue()) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(1 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) {
self.animation?.play() self.animation?.play()
} }
} }
func updateScale(scale: Float) { func updateScale(_ scale: Float) {
let rotation = GeomUtils.centerRotation(node: sceneGroup, place: initialTransform, angle: M_PI_4 * Double(scale)) let rotation = GeomUtils.centerRotation(node: sceneGroup, place: initialTransform, angle: M_PI_4 * Double(scale))
sceneGroup.place = rotation// GeomUtils.concat(t1: rotation, t2: initialTransform) sceneGroup.place = rotation// GeomUtils.concat(t1: rotation, t2: initialTransform)
} }
private static func newScene() -> Node { fileprivate static func newScene() -> Node {
let shape = Shape(form: Rect(x: -50, y: -50, w: 100, h: 100), fill: Color.blue) let shape = Shape(form: Rect(x: -50, y: -50, w: 100, h: 100), fill: Color.blue)
let t1 = Transform.identity let t1 = Transform.identity
let t2 = GeomUtils.centerRotation(node: shape, place: Transform.identity, angle: M_PI_4) // Transform.rotate(angle: M_PI_4) let t2 = GeomUtils.centerRotation(node: shape, place: Transform.identity, angle: M_PI_4) // Transform.rotate(angle: M_PI_4)

View File

@ -73,7 +73,7 @@ class ShapesExampleView: MacawView {
super.init(node: group, coder: aDecoder) super.init(node: group, coder: aDecoder)
} }
private static func newText(text: String, _ place: Transform, baseline: Baseline = .bottom) -> Text { fileprivate static func newText(_ text: String, _ place: Transform, baseline: Baseline = .bottom) -> Text {
return Text(text: text, fill: Color.black, baseline: baseline, align: .mid, place: place) return Text(text: text, fill: Color.black, baseline: baseline, align: .mid, place: place)
} }

View File

@ -13,12 +13,12 @@ import Macaw
class TransformExampleView: MacawView { class TransformExampleView: MacawView {
private static let transforms = [Transform.scale(sx: 2, sy: 2), fileprivate static let transforms = [Transform.scale(sx: 2, sy: 2),
Transform.move(dx: 100, dy: 30), Transform.move(dx: 100, dy: 30),
Transform.rotate(angle: M_PI_4, x: 150, y: 80), Transform.rotate(angle: M_PI_4, x: 150, y: 80),
Transform.rotate(angle: M_PI_4)] Transform.rotate(angle: M_PI_4)]
private static let titles = ["Transform.scale(sx: 2, sy: 2)", fileprivate static let titles = ["Transform.scale(sx: 2, sy: 2)",
"Transform.move(dx: 100, dy: 30)", "Transform.move(dx: 100, dy: 30)",
"Transform.rotate(angle: M_PI_4, x: 150, y: 80)", "Transform.rotate(angle: M_PI_4, x: 150, y: 80)",
"Transform.rotate(angle: M_PI_4)"] "Transform.rotate(angle: M_PI_4)"]
@ -27,10 +27,10 @@ class TransformExampleView: MacawView {
super.init(node: TransformExampleView.newScene(), coder: aDecoder) super.init(node: TransformExampleView.newScene(), coder: aDecoder)
} }
private static func newScene() -> Node { fileprivate static func newScene() -> Node {
let shape = Shape(form: Rect(x: 0, y: 0, w: 50, h: 50), fill: Color.blue) let shape = Shape(form: Rect(x: 0, y: 0, w: 50, h: 50), fill: Color.blue)
let textes = Group(place: .move(dx: 50, dy: 275)) let textes = Group(place: .move(dx: 50, dy: 275))
for (i, item) in titles.enumerate() { for (i, item) in titles.enumerated() {
let place = Transform.move(dx: 0, dy: Double(i * 25)) let place = Transform.move(dx: 0, dy: Double(i * 25))
textes.contents.append(Text(text: item, baseline: .bottom, place: place, opacity: 0)) textes.contents.append(Text(text: item, baseline: .bottom, place: place, opacity: 0))
} }
@ -53,7 +53,7 @@ class TransformExampleView: MacawView {
return Group(contents: [newAxes(), shape, textes], place: .move(dx: 10, dy: 30)) return Group(contents: [newAxes(), shape, textes], place: .move(dx: 10, dy: 30))
} }
private static func newAxes() -> Node { fileprivate static func newAxes() -> Node {
var items: [Node] = [] var items: [Node] = []
let gray = Color(val: 0xF0F0F0) let gray = Color(val: 0xF0F0F0)
for i in 1...20 { for i in 1...20 {

View File

@ -10,11 +10,11 @@ class MenuViewController: UIViewController, UITableViewDataSource, UITableViewDe
} }
} }
func numberOfSectionsInTableView(tableView: UITableView) -> Int { func numberOfSections(in tableView: UITableView) -> Int {
return 1 return 1
} }
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let count = viewControllers?.count else { guard let count = viewControllers?.count else {
return 0 return 0
} }
@ -22,22 +22,22 @@ class MenuViewController: UIViewController, UITableViewDataSource, UITableViewDe
return count return count
} }
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("menu_cell")! let cell = tableView.dequeueReusableCell(withIdentifier: "menu_cell")!
if let viewController = viewControllers?[indexPath.row] { if let viewController = viewControllers?[(indexPath as NSIndexPath).row] {
cell.textLabel?.text = viewController.title cell.textLabel?.text = viewController.title
} }
return cell return cell
} }
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let selectedCtrl = viewControllers?[indexPath.row] else { guard let selectedCtrl = viewControllers?[(indexPath as NSIndexPath).row] else {
return return
} }
pageViewController?.setViewControllers([selectedCtrl], pageViewController?.setViewControllers([selectedCtrl],
direction: .Forward, animated: true, completion: nil) direction: .forward, animated: true, completion: nil)
} }
} }

View File

@ -1,9 +1,9 @@
PODS: PODS:
- Macaw (0.1.0): - Macaw (0.1.0):
- RxSwift (~> 2.0s) - RxSwift (= 3.0.0-beta.1)
- SWXMLHash (~> 2.3.0) - SWXMLHash (~> 3.0.0)
- RxSwift (2.6.0) - RxSwift (3.0.0-beta.1)
- SWXMLHash (2.3.2) - SWXMLHash (3.0.2)
DEPENDENCIES: DEPENDENCIES:
- Macaw (from `../`) - Macaw (from `../`)
@ -13,9 +13,9 @@ EXTERNAL SOURCES:
:path: ../ :path: ../
SPEC CHECKSUMS: SPEC CHECKSUMS:
Macaw: 6d8c002627caf979148fd395770caf12112ecc2b Macaw: 34daf17a1bacaea417aef1eeb1647123d43d6af5
RxSwift: 77f3a0b15324baa7a1c9bfa9f199648a82424e26 RxSwift: 0823e8d7969c23bfa9ddfb2afa4881e424a1a710
SWXMLHash: 2f8c49af765718ad56020c4f875ec3ff22612f06 SWXMLHash: e0f6935971f01b06fb228cf435510d998ecde647
PODFILE CHECKSUM: 151f0be871736eddfeeec5cda1747f8a81e679ef PODFILE CHECKSUM: 151f0be871736eddfeeec5cda1747f8a81e679ef

View File

@ -28,7 +28,7 @@ Pod::Spec.new do |s|
s.platform = :ios, '8.0' s.platform = :ios, '8.0'
s.requires_arc = true s.requires_arc = true
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '2.3' } s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' }
s.source_files = [ s.source_files = [
'Source/*.swift', 'Source/*.swift',
@ -57,6 +57,6 @@ Pod::Spec.new do |s|
# s.public_header_files = 'Pod/Classes/**/*.h' # s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit' # s.frameworks = 'UIKit', 'MapKit'
s.dependency 'SWXMLHash', '~> 2.3.0' s.dependency 'SWXMLHash', '~> 3.0.0'
s.dependency 'RxSwift', '~> 2.0s ' s.dependency 'RxSwift', '3.0.0-beta.1'
end end

View File

@ -8,7 +8,7 @@
import RxSwift import RxSwift
public class AnimatableVariable<T: Interpolable> : Variable<T> { open class AnimatableVariable<T: Interpolable> : Variable<T> {
internal var node: Node? internal var node: Node?

View File

@ -1,35 +1,35 @@
public class Animation { open class Animation {
internal init() { internal init() {
} }
public func play() { open func play() {
} }
public func stop() { open func stop() {
} }
public func easing(easing: Easing) -> Animation { open func easing(_ easing: Easing) -> Animation {
return self return self
} }
public func delay(delay: Double) -> Animation { open func delay(_ delay: Double) -> Animation {
return self return self
} }
public func cycle(count: Double) -> Animation { open func cycle(_ count: Double) -> Animation {
return self return self
} }
public func reverse() -> Animation { open func reverse() -> Animation {
return self return self
} }
public func autoreversed() -> Animation { open func autoreversed() -> Animation {
return self return self
} }
public func onComplete(_: (() -> ())) -> Animation { open func onComplete(_: (() -> ())) -> Animation {
return self return self
} }
} }

View File

@ -10,18 +10,18 @@ import Foundation
import RxSwift import RxSwift
enum AnimationType { enum AnimationType {
case Unknown case unknown
case AffineTransformation case affineTransformation
case Opacity case opacity
case Sequence case sequence
case Combine case combine
case Empty case empty
} }
class BasicAnimation: Animation { class BasicAnimation: Animation {
var node: Node? var node: Node?
var type = AnimationType.Unknown var type = AnimationType.unknown
let ID: String let ID: String
var next: BasicAnimation? var next: BasicAnimation?
var removeFunc: (() -> ())? var removeFunc: (() -> ())?
@ -31,49 +31,49 @@ class BasicAnimation: Animation {
var delay = 0.0 var delay = 0.0
var autoreverses = false var autoreverses = false
var onProgressUpdate: ((Double) -> ())? var onProgressUpdate: ((Double) -> ())?
var easing = Easing.Ease var easing = Easing.ease
var completion: (() -> ())? var completion: (() -> ())?
override init() { override init() {
ID = NSUUID().UUIDString ID = UUID().uuidString
super.init() super.init()
} }
override public func delay(delay: Double) -> Animation { override open func delay(_ delay: Double) -> Animation {
self.delay += delay self.delay += delay
return self return self
} }
override public func cycle(count: Double) -> Animation { override open func cycle(_ count: Double) -> Animation {
self.repeatCount = count self.repeatCount = count
return self return self
} }
override public func easing(easing: Easing) -> Animation { override open func easing(_ easing: Easing) -> Animation {
self.easing = easing self.easing = easing
return self return self
} }
override public func autoreversed() -> Animation { override open func autoreversed() -> Animation {
self.autoreverses = true self.autoreverses = true
return self return self
} }
override public func onComplete(f: (() -> ())) -> Animation { override open func onComplete(_ f: @escaping (() -> ())) -> Animation {
self.completion = f self.completion = f
return self return self
} }
override public func play() { override open func play() {
animationProducer.addAnimation(self) animationProducer.addAnimation(self)
} }
override public func stop() { override open func stop() {
manualStop = true manualStop = true
removeFunc?() removeFunc?()
} }
override public func reverse() -> Animation { override open func reverse() -> Animation {
return self return self
} }
@ -89,9 +89,9 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
let duration: Double let duration: Double
let logicalFps: UInt let logicalFps: UInt
private var vFunc: ((Double) -> T)? fileprivate var vFunc: ((Double) -> T)?
init(observableValue: Variable<T>, valueFunc: (Double) -> T, animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) { init(observableValue: Variable<T>, valueFunc: @escaping (Double) -> T, animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
self.value = observableValue self.value = observableValue
self.duration = animationDuration self.duration = animationDuration
self.timeFactory = { (node) in return valueFunc } self.timeFactory = { (node) in return valueFunc }
@ -103,7 +103,7 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
self.delay = delay self.delay = delay
} }
init(observableValue: Variable<T>, factory: ((Node) -> ((Double) -> T)), animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) { init(observableValue: Variable<T>, factory: @escaping ((Node) -> ((Double) -> T)), animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
self.value = observableValue self.value = observableValue
self.duration = animationDuration self.duration = animationDuration
self.timeFactory = factory self.timeFactory = factory
@ -126,11 +126,11 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
self.init(observableValue: observableValue, startValue: observableValue.value, finalValue: finalValue, animationDuration: animationDuration) self.init(observableValue: observableValue, startValue: observableValue.value, finalValue: finalValue, animationDuration: animationDuration)
} }
public override func getDuration() -> Double { open override func getDuration() -> Double {
return duration return duration
} }
public func getVFunc() -> ((Double) -> T) { open func getVFunc() -> ((Double) -> T) {
if (vFunc == nil) { if (vFunc == nil) {
vFunc = timeFactory(self.node!) vFunc = timeFactory(self.node!)
} }
@ -141,27 +141,27 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
// For sequence completion // For sequence completion
class EmptyAnimation: BasicAnimation { class EmptyAnimation: BasicAnimation {
required init(completion: (() -> ())) { required init(completion: @escaping (() -> ())) {
super.init() super.init()
self.completion = completion self.completion = completion
self.type = .Empty self.type = .empty
} }
} }
// MARK: - Animation Description // MARK: - Animation Description
public class AnimationDescription <T> { open class AnimationDescription <T> {
public let valueFunc: (Double) -> T open let valueFunc: (Double) -> T
public var duration = 0.0 open var duration = 0.0
public var delay = 0.0 open var delay = 0.0
public init(valueFunc: (Double) -> T, duration: Double = 1.0, delay: Double = 0.0) { public init(valueFunc: @escaping (Double) -> T, duration: Double = 1.0, delay: Double = 0.0) {
self.valueFunc = valueFunc self.valueFunc = valueFunc
self.duration = duration self.duration = duration
self.delay = delay self.delay = delay
} }
public func t(duration: Double, delay: Double = 0.0) -> AnimationDescription<T> { open func t(_ duration: Double, delay: Double = 0.0) -> AnimationDescription<T> {
return AnimationDescription(valueFunc: valueFunc, duration: duration, delay: delay) return AnimationDescription(valueFunc: valueFunc, duration: duration, delay: delay)
} }
} }

View File

@ -6,18 +6,18 @@ class AnimationProducer {
var storedAnimations = [Node: BasicAnimation]() var storedAnimations = [Node: BasicAnimation]()
func addAnimation(animation: BasicAnimation, withoutDelay: Bool = false) { func addAnimation(_ animation: BasicAnimation, withoutDelay: Bool = false) {
if animation.delay > 0.0 && !withoutDelay { if animation.delay > 0.0 && !withoutDelay {
NSTimer.schedule(delay: animation.delay, handler: { _ in Timer.schedule(delay: animation.delay, handler: { _ in
self.addAnimation(animation, withoutDelay: true) self.addAnimation(animation, withoutDelay: true)
}) })
return return
} }
if animation.type == .Empty { if animation.type == .empty {
executeCompletion(animation) executeCompletion(animation)
return return
} }
@ -36,30 +36,30 @@ class AnimationProducer {
} }
switch animation.type { switch animation.type {
case .Unknown: case .unknown:
return return
case .AffineTransformation: case .affineTransformation:
addTransformAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: { addTransformAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
if let next = animation.next { if let next = animation.next {
self.addAnimation(next) self.addAnimation(next)
} }
}) })
case .Opacity: case .opacity:
addOpacityAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: { addOpacityAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
if let next = animation.next { if let next = animation.next {
self.addAnimation(next) self.addAnimation(next)
} }
}) })
case .Sequence: case .sequence:
addAnimationSequence(animation) addAnimationSequence(animation)
case .Combine: case .combine:
addCombineAnimation(animation) addCombineAnimation(animation)
case .Empty: case .empty:
executeCompletion(animation) executeCompletion(animation)
} }
} }
private func addAnimationSequence(animationSequnce: Animation) { fileprivate func addAnimationSequence(_ animationSequnce: Animation) {
guard let sequence = animationSequnce as? AnimationSequence else { guard let sequence = animationSequnce as? AnimationSequence else {
return return
} }
@ -74,14 +74,14 @@ class AnimationProducer {
var sequenceAnimations = [BasicAnimation]() var sequenceAnimations = [BasicAnimation]()
if sequence.repeatCount > 0.0001 { if sequence.repeatCount > 0.0001 {
for i in 0..<Int(sequence.repeatCount) { for i in 0..<Int(sequence.repeatCount) {
sequenceAnimations.appendContentsOf(sequence.animations) sequenceAnimations.append(contentsOf: sequence.animations)
} }
} else { } else {
sequenceAnimations.appendContentsOf(sequence.animations) sequenceAnimations.append(contentsOf: sequence.animations)
} }
if sequence.autoreverses { if sequence.autoreverses {
sequenceAnimations = sequenceAnimations.reverse() sequenceAnimations = sequenceAnimations.reversed()
} }
// Connecting animations // Connecting animations
@ -111,7 +111,7 @@ class AnimationProducer {
} }
} }
private func addCombineAnimation(combineAnimation: Animation) { fileprivate func addCombineAnimation(_ combineAnimation: Animation) {
guard let combine = combineAnimation as? CombineAnimation else { guard let combine = combineAnimation as? CombineAnimation else {
return return
} }
@ -177,14 +177,14 @@ class AnimationProducer {
} }
} }
private func executeCompletion(emptyAnimation: BasicAnimation) { fileprivate func executeCompletion(_ emptyAnimation: BasicAnimation) {
emptyAnimation.completion?() emptyAnimation.completion?()
} }
func addStoredAnimations(node: Node) { func addStoredAnimations(_ node: Node) {
if let animation = storedAnimations[node] { if let animation = storedAnimations[node] {
addAnimation(animation) addAnimation(animation)
storedAnimations.removeValueForKey(node) storedAnimations.removeValue(forKey: node)
} }
guard let group = node as? Group else { guard let group = node as? Group else {

View File

@ -2,14 +2,14 @@
import Foundation import Foundation
class AnimationUtils { class AnimationUtils {
class func absolutePosition(node: Node) -> Transform { class func absolutePosition(_ node: Node) -> Transform {
return AnimationUtils.absoluteTransform(node, pos: node.place) return AnimationUtils.absoluteTransform(node, pos: node.place)
} }
class func absoluteTransform(node: Node, pos: Transform) -> Transform { class func absoluteTransform(_ node: Node, pos: Transform) -> Transform {
var transform = pos var transform = pos
var parent = nodesMap.parents(node).first var parent = nodesMap.parents(node).first
while parent != .None { while parent != .none {
transform = GeomUtils.concat(t1: parent!.place, t2: transform) transform = GeomUtils.concat(t1: parent!.place, t2: transform)
parent = nodesMap.parents(parent!).first parent = nodesMap.parents(parent!).first
} }

View File

@ -7,9 +7,9 @@
// //
public enum Easing { public enum Easing {
case Ease case ease
case Linear case linear
case EaseIn case easeIn
case EaseOut case easeOut
case EaseInOut case easeInOut
} }

View File

@ -14,12 +14,12 @@ public extension Rect {
return CGRect(x: self.x, y: self.y, width: self.w, height: self.h) return CGRect(x: self.x, y: self.y, width: self.w, height: self.h)
} }
func applyTransform(transform: Transform) -> Rect { func applyTransform(_ transform: Transform) -> Rect {
// TODO: Rewrite using math // TODO: Rewrite using math
let cgTransform = RenderUtils.mapTransform(transform) let cgTransform = RenderUtils.mapTransform(transform)
return Rect(cgRect: CGRectApplyAffineTransform(self.cgRect(), cgTransform)) return Rect(cgRect: self.cgRect().applying(cgTransform))
} }
public func description() -> String { public func description() -> String {

View File

@ -5,7 +5,7 @@ public protocol DoubleInterpolation: Interpolable {
} }
extension Double: DoubleInterpolation { extension Double: DoubleInterpolation {
public func interpolate(endValue: Double, progress: Double) -> Double { public func interpolate(_ endValue: Double, progress: Double) -> Double {
return self + (endValue - self) * progress return self + (endValue - self) * progress
} }

View File

@ -1,5 +1,5 @@
import Foundation import Foundation
public protocol Interpolable { public protocol Interpolable {
func interpolate(endValue: Self, progress: Double) -> Self func interpolate(_ endValue: Self, progress: Double) -> Self
} }

View File

@ -5,7 +5,7 @@ public protocol TransformInterpolation: Interpolable {
} }
extension Transform: TransformInterpolation { extension Transform: TransformInterpolation {
public func interpolate(endValue: Transform, progress: Double) -> Transform { public func interpolate(_ endValue: Transform, progress: Double) -> Transform {
return Transform(m11: self.m11.interpolate(endValue.m11, progress: progress), return Transform(m11: self.m11.interpolate(endValue.m11, progress: progress),
m12: self.m12.interpolate(endValue.m12, progress: progress), m12: self.m12.interpolate(endValue.m12, progress: progress),
m21: self.m21.interpolate(endValue.m21, progress: progress), m21: self.m21.interpolate(endValue.m21, progress: progress),

View File

@ -1,15 +1,15 @@
func boundsForFunc(func2d: func2D) -> Rect { func boundsForFunc(_ func2d: func2D) -> Rect {
var p = func2d(t: 0.0) var p = func2d(0.0)
var minX = p.x var minX = p.x
var minY = p.y var minY = p.y
var maxX = minX var maxX = minX
var maxY = minY var maxY = minY
for t in 0.0.stride(to: 1.0, by: 0.01) { for t in stride(from: 0.0, to: 1.0, by: 0.01) {
p = func2d(t: t) p = func2d(t)
if minX > p.x { if minX > p.x {
minX = p.x minX = p.x

View File

@ -1,11 +1,11 @@
func pathBounds(path: Path) -> Rect? { func pathBounds(_ path: Path) -> Rect? {
guard let firstSegment = path.segments.first else { guard let firstSegment = path.segments.first else {
return .None return .none
} }
let firstSegmentInfo = pathSegmenInfo(firstSegment, currentPoint: .None, currentBezierPoint: .None) let firstSegmentInfo = pathSegmenInfo(firstSegment, currentPoint: .none, currentBezierPoint: .none)
var bounds = firstSegmentInfo.0 var bounds = firstSegmentInfo.0
var currentPoint = firstSegmentInfo.1 ?? Point.origin var currentPoint = firstSegmentInfo.1 ?? Point.origin
var cubicBezierPoint: Point? var cubicBezierPoint: Point?
@ -40,19 +40,19 @@ func pathBounds(path: Path) -> Rect? {
return bounds return bounds
} }
func pathSegmenInfo(segment: PathSegment, currentPoint: Point?, currentBezierPoint: Point?) func pathSegmenInfo(_ segment: PathSegment, currentPoint: Point?, currentBezierPoint: Point?)
-> (Rect?, Point?, Point?) { // Bounds, last point, last bezier point TODO: Replace as struct -> (Rect?, Point?, Point?) { // Bounds, last point, last bezier point TODO: Replace as struct
let data = segment.data let data = segment.data
switch segment.type { switch segment.type {
case .m, .M: case .m, .M:
let point = Point(x: data[0], y: data[1]) let point = Point(x: data[0], y: data[1])
return (Rect(x: point.x, y: point.y, w: 0.0, h: 0.0), point, .None) return (Rect(x: point.x, y: point.y, w: 0.0, h: 0.0), point, .none)
case .c, .C: case .c, .C:
return (cubicBounds(data), Point(x: data[4], y: data[5]), Point(x: data[2], y: data[3])) return (cubicBounds(data), Point(x: data[4], y: data[5]), Point(x: data[2], y: data[3]))
case .s, .S: case .s, .S:
guard let currentPoint = currentPoint else { guard let currentPoint = currentPoint else {
return (.None, .None, .None) return (.none, .none, .none)
} }
var p2 = currentPoint var p2 = currentPoint
@ -66,17 +66,17 @@ func pathSegmenInfo(segment: PathSegment, currentPoint: Point?, currentBezierPoi
Point(x: data[2], y: data[3]), Point(x: data[2], y: data[3]),
Point(x: p2.x, y: p2.y)) Point(x: p2.x, y: p2.y))
case .h, .H: case .h, .H:
return (Rect(x: 0.0, y: 0.0, w: data[0], h: 0.0), Point(x: data[0], y: 0.0), .None) return (Rect(x: 0.0, y: 0.0, w: data[0], h: 0.0), Point(x: data[0], y: 0.0), .none)
case .v, .V: case .v, .V:
return (Rect(x: 0.0, y: 0.0, w: 0.0, h: data[0]), Point(x: 0.0, y: data[0]), .None) return (Rect(x: 0.0, y: 0.0, w: 0.0, h: data[0]), Point(x: 0.0, y: data[0]), .none)
case .l, .L: case .l, .L:
return (Rect(x: data[0], y: data[1], w: 0.0, h: 0.0), Point(x: data[0], y: data[1]), .None) return (Rect(x: data[0], y: data[1], w: 0.0, h: 0.0), Point(x: data[0], y: data[1]), .none)
default: default:
return (.None, .None, .None) return (.none, .none, .none)
} }
} }
private func cubicBounds(data: [Double]) -> Rect { private func cubicBounds(_ data: [Double]) -> Rect {
let p0 = Point(x: 0, y: 0) let p0 = Point(x: 0, y: 0)
let p1 = Point(x: data[0], y: data[1]) let p1 = Point(x: data[0], y: data[1])
let p2 = Point(x: data[2], y: data[3]) let p2 = Point(x: data[2], y: data[3])
@ -88,7 +88,7 @@ private func cubicBounds(data: [Double]) -> Rect {
return boundsForFunc(bezier3) return boundsForFunc(bezier3)
} }
private func sCubicBounds(data: [Double], currentPoint: Point, currentBezierPoint: Point?) -> Rect { private func sCubicBounds(_ data: [Double], currentPoint: Point, currentBezierPoint: Point?) -> Rect {
let p0 = Point(x: 0, y: 0) let p0 = Point(x: 0, y: 0)
let p1 = Point(x: data[0], y: data[1]) let p1 = Point(x: data[0], y: data[1])

View File

@ -1,14 +1,14 @@
import Foundation import Foundation
typealias func2D = ((t: Double) -> (Point)) typealias func2D = ((_ t: Double) -> (Point))
func BezierFunc2D(t: Double, p0: Point, p1: Point, p2: Point, p3: Point) -> Point { func BezierFunc2D(_ t: Double, p0: Point, p1: Point, p2: Point, p3: Point) -> Point {
return Point( return Point(
x: polynom3(t, p0: p0.x, p1: p1.x, p2: p2.x, p3: p3.x), x: polynom3(t, p0: p0.x, p1: p1.x, p2: p2.x, p3: p3.x),
y: polynom3(t, p0: p0.y, p1: p1.y, p2: p2.y, p3: p3.y)) y: polynom3(t, p0: p0.y, p1: p1.y, p2: p2.y, p3: p3.y))
} }
func polynom3(t: Double, p0: Double, p1: Double, p2: Double, p3: Double) -> Double { func polynom3(_ t: Double, p0: Double, p1: Double, p2: Double, p3: Double) -> Double {
let t1 = 1.0 - t let t1 = 1.0 - t
return pow(t1, 3.0) * p0 + 3.0 * t * pow(t1, 2.0) * p1 + 3.0 * t * t * t1 * p2 + pow(t, 3.0) * p3 return pow(t1, 3.0) * p0 + 3.0 * t * pow(t1, 2.0) * p1 + 3.0 * t * t * t1 * p2 + pow(t, 3.0) * p3
} }

View File

@ -10,28 +10,28 @@ internal class AnimationSequence: BasicAnimation {
super.init() super.init()
self.type = .Sequence self.type = .sequence
self.node = animations.first?.node self.node = animations.first?.node
self.delay = delay self.delay = delay
} }
override func getDuration() -> Double { override func getDuration() -> Double {
return animations.map({ $0.getDuration() }).reduce(0, combine: { $0 + $1 }) return animations.map({ $0.getDuration() }).reduce(0, { $0 + $1 })
} }
public override func stop() { open override func stop() {
animations.forEach { animation in animations.forEach { animation in
animation.stop() animation.stop()
} }
} }
public override func reverse() -> Animation { open override func reverse() -> Animation {
var reversedAnimations = [BasicAnimation]() var reversedAnimations = [BasicAnimation]()
animations.forEach { animation in animations.forEach { animation in
reversedAnimations.append(animation.reverse() as! BasicAnimation) reversedAnimations.append(animation.reverse() as! BasicAnimation)
} }
let reversedSequence = reversedAnimations.reverse().sequence(delay: self.delay) as! BasicAnimation let reversedSequence = reversedAnimations.reversed().sequence(delay: self.delay) as! BasicAnimation
reversedSequence.completion = completion reversedSequence.completion = completion
reversedSequence.progress = progress reversedSequence.progress = progress
@ -39,8 +39,8 @@ internal class AnimationSequence: BasicAnimation {
} }
} }
public extension SequenceType where Generator.Element: Animation { public extension Sequence where Iterator.Element: Animation {
public func sequence(delay delay: Double = 0.0) -> Animation { public func sequence(delay: Double = 0.0) -> Animation {
var sequence = [BasicAnimation]() var sequence = [BasicAnimation]()
self.forEach { animation in self.forEach { animation in

View File

@ -10,21 +10,21 @@ internal class CombineAnimation: BasicAnimation {
super.init() super.init()
self.type = .Combine self.type = .combine
self.node = animations.first?.node self.node = animations.first?.node
self.delay = delay self.delay = delay
} }
override func getDuration() -> Double { override func getDuration() -> Double {
if let maxElement = animations.map({ $0.getDuration() }).maxElement() { if let maxElement = animations.map({ $0.getDuration() }).max() {
return maxElement return maxElement
} }
return 0.0 return 0.0
} }
public override func reverse() -> Animation { open override func reverse() -> Animation {
var reversedAnimations = [BasicAnimation]() var reversedAnimations = [BasicAnimation]()
animations.forEach { animation in animations.forEach { animation in
reversedAnimations.append(animation.reverse() as! BasicAnimation) reversedAnimations.append(animation.reverse() as! BasicAnimation)
@ -37,15 +37,15 @@ internal class CombineAnimation: BasicAnimation {
return combineReversed return combineReversed
} }
public override func stop() { open override func stop() {
animations.forEach { animation in animations.forEach { animation in
animation.stop() animation.stop()
} }
} }
} }
public extension SequenceType where Generator.Element: Animation { public extension Sequence where Iterator.Element: Animation {
public func combine(delay delay: Double = 0.0) -> Animation { public func combine(delay: Double = 0.0) -> Animation {
var toCombine = [BasicAnimation]() var toCombine = [BasicAnimation]()
self.forEach { animation in self.forEach { animation in
@ -53,4 +53,4 @@ public extension SequenceType where Generator.Element: Animation {
} }
return CombineAnimation(animations: toCombine, delay: delay) return CombineAnimation(animations: toCombine, delay: delay)
} }
} }

View File

@ -14,7 +14,7 @@ internal class OpacityAnimation: AnimationImpl<Double> {
init(animatedNode: Node, valueFunc: (Double) -> Double, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) { init(animatedNode: Node, valueFunc: (Double) -> Double, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
super.init(observableValue: animatedNode.opacityVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps) super.init(observableValue: animatedNode.opacityVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
type = .Opacity type = .opacity
node = animatedNode node = animatedNode
if autostart { if autostart {
@ -24,7 +24,7 @@ internal class OpacityAnimation: AnimationImpl<Double> {
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Double)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) { init(animatedNode: Node, factory: ((Node) -> ((Double) -> Double)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
super.init(observableValue: animatedNode.opacityVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps) super.init(observableValue: animatedNode.opacityVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
type = .Opacity type = .opacity
node = animatedNode node = animatedNode
if autostart { if autostart {
@ -32,7 +32,7 @@ internal class OpacityAnimation: AnimationImpl<Double> {
} }
} }
public override func reverse() -> Animation { open override func reverse() -> Animation {
let factory = { (node: Node) -> (Double) -> Double in let factory = { (node: Node) -> (Double) -> Double in
let original = self.timeFactory(node) let original = self.timeFactory(node)
return { (t: Double) -> Double in return { (t: Double) -> Double in
@ -52,19 +52,19 @@ internal class OpacityAnimation: AnimationImpl<Double> {
public typealias OpacityAnimationDescription = AnimationDescription<Double> public typealias OpacityAnimationDescription = AnimationDescription<Double>
public extension AnimatableVariable where T: DoubleInterpolation { public extension AnimatableVariable where T: DoubleInterpolation {
public func animate(desc: OpacityAnimationDescription) { public func animate(_ desc: OpacityAnimationDescription) {
let _ = OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true) let _ = OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
} }
public func animation(desc: OpacityAnimationDescription) -> Animation { public func animation(_ desc: OpacityAnimationDescription) -> Animation {
return OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false) return OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
} }
public func animate(from from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) { public func animate(from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) {
self.animate(((from ?? node!.opacity) >> to).t(during, delay: delay)) self.animate(((from ?? node!.opacity) >> to).t(during, delay: delay))
} }
public func animation(from from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) -> Animation { public func animation(from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
if let safeFrom = from { if let safeFrom = from {
return self.animation((safeFrom >> to).t(during, delay: delay)) return self.animation((safeFrom >> to).t(during, delay: delay))
} }
@ -75,7 +75,7 @@ public extension AnimatableVariable where T: DoubleInterpolation {
return OpacityAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay) return OpacityAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
} }
public func animation(f: (Double) -> Double, during: Double = 1.0, delay: Double = 0.0) -> Animation { public func animation(_ f: (Double) -> Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
return OpacityAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay) return OpacityAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
} }

View File

@ -13,7 +13,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
init(animatedNode: Node, valueFunc: (Double) -> Transform, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) { init(animatedNode: Node, valueFunc: (Double) -> Transform, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
super.init(observableValue: animatedNode.placeVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps) super.init(observableValue: animatedNode.placeVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
type = .AffineTransformation type = .affineTransformation
node = animatedNode node = animatedNode
if autostart { if autostart {
@ -23,7 +23,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Transform)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) { init(animatedNode: Node, factory: ((Node) -> ((Double) -> Transform)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps) super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
type = .AffineTransformation type = .affineTransformation
node = animatedNode node = animatedNode
if autostart { if autostart {
@ -31,7 +31,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
} }
} }
public override func reverse() -> Animation { open override func reverse() -> Animation {
let factory = { (node: Node) -> (Double) -> Transform in let factory = { (node: Node) -> (Double) -> Transform in
let original = self.timeFactory(node) let original = self.timeFactory(node)
@ -52,19 +52,19 @@ internal class TransformAnimation: AnimationImpl<Transform> {
public typealias TransformAnimationDescription = AnimationDescription<Transform> public typealias TransformAnimationDescription = AnimationDescription<Transform>
public extension AnimatableVariable where T: TransformInterpolation { public extension AnimatableVariable where T: TransformInterpolation {
public func animate(desc: TransformAnimationDescription) { public func animate(_ desc: TransformAnimationDescription) {
let _ = TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true) let _ = TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
} }
public func animation(desc: TransformAnimationDescription) -> Animation { public func animation(_ desc: TransformAnimationDescription) -> Animation {
return TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false) return TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
} }
public func animate(from from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) { public func animate(from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) {
self.animate(((from ?? node!.place) >> to).t(during, delay: delay)) self.animate(((from ?? node!.place) >> to).t(during, delay: delay))
} }
public func animation(from from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) -> Animation { public func animation(from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) -> Animation {
if let safeFrom = from { if let safeFrom = from {
return self.animation((safeFrom >> to).t(during, delay: delay)) return self.animation((safeFrom >> to).t(during, delay: delay))
} }
@ -75,7 +75,7 @@ public extension AnimatableVariable where T: TransformInterpolation {
return TransformAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay) return TransformAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
} }
public func animation(f: (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation { public func animation(_ f: (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation {
return TransformAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay) return TransformAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
} }

View File

@ -22,7 +22,7 @@ class AnimationCache {
self.sceneLayer = sceneLayer self.sceneLayer = sceneLayer
} }
func layerForNode(node: Node, animation: Animation) -> ShapeLayer { func layerForNode(_ node: Node, animation: Animation) -> ShapeLayer {
guard let cachedLayer = layerCache[node] else { guard let cachedLayer = layerCache[node] else {
let layer = ShapeLayer() let layer = ShapeLayer()
layer.animationCache = self layer.animationCache = self
@ -35,17 +35,17 @@ class AnimationCache {
if let shapeBounds = node.bounds() { if let shapeBounds = node.bounds() {
let cgRect = shapeBounds.cgRect() let cgRect = shapeBounds.cgRect()
let origFrame = CGRectMake(0.0, 0.0, let origFrame = CGRect(x: 0.0, y: 0.0,
round(cgRect.width), width: round(cgRect.width),
round(cgRect.height)) height: round(cgRect.height))
layer.bounds = origFrame layer.bounds = origFrame
layer.anchorPoint = CGPointMake( layer.anchorPoint = CGPoint(
-1.0 * cgRect.origin.x / cgRect.width, x: -1.0 * cgRect.origin.x / cgRect.width,
-1.0 * cgRect.origin.y / cgRect.height y: -1.0 * cgRect.origin.y / cgRect.height
) )
layer.renderTransform = CGAffineTransformMakeTranslation(-1.0 * cgRect.origin.x, -1.0 * cgRect.origin.y) layer.renderTransform = CGAffineTransform(translationX: -1.0 * cgRect.origin.x, y: -1.0 * cgRect.origin.y)
let nodeTransform = RenderUtils.mapTransform(AnimationUtils.absolutePosition(node)) let nodeTransform = RenderUtils.mapTransform(AnimationUtils.absolutePosition(node))
layer.transform = CATransform3DMakeAffineTransform(nodeTransform) layer.transform = CATransform3DMakeAffineTransform(nodeTransform)
@ -67,7 +67,7 @@ class AnimationCache {
return cachedLayer.layer return cachedLayer.layer
} }
func freeLayer(node: Node) { func freeLayer(_ node: Node) {
guard let cachedLayer = layerCache[node] else { guard let cachedLayer = layerCache[node] else {
return return
} }
@ -79,12 +79,12 @@ class AnimationCache {
} }
let layer = cachedLayer.layer let layer = cachedLayer.layer
layerCache.removeValueForKey(node) layerCache.removeValue(forKey: node)
sceneLayer.setNeedsDisplay() sceneLayer.setNeedsDisplay()
layer.removeFromSuperlayer() layer.removeFromSuperlayer()
} }
func isAnimating(node: Node) -> Bool { func isAnimating(_ node: Node) -> Bool {
if let _ = layerCache[node] { if let _ = layerCache[node] {
return true return true
@ -93,7 +93,7 @@ class AnimationCache {
return false return false
} }
func isChildrenAnimating(group: Group) -> Bool { func isChildrenAnimating(_ group: Group) -> Bool {
for child in group.contents { for child in group.contents {
if isAnimating(child) { if isAnimating(child) {
@ -108,7 +108,7 @@ class AnimationCache {
return false return false
} }
func containsAnimation(node: Node) -> Bool { func containsAnimation(_ node: Node) -> Bool {
if isAnimating(node) { if isAnimating(node) {
return true return true
} }

View File

@ -1,16 +1,16 @@
import Foundation import Foundation
let animationRestorer = AnimationRestorer() let animationRestorer = AnimationRestorer()
public class AnimationRestorer { open class AnimationRestorer {
typealias RestoreClosure = () -> () typealias RestoreClosure = () -> ()
var restoreClosures = [RestoreClosure]() var restoreClosures = [RestoreClosure]()
func addRestoreClosure(closure: RestoreClosure) { func addRestoreClosure(_ closure: @escaping RestoreClosure) {
restoreClosures.append(closure) restoreClosures.append(closure)
} }
public class func restore() { open class func restore() {
dispatch_async(dispatch_get_main_queue()) { DispatchQueue.main.async {
animationRestorer.restoreClosures.forEach { restoreClosure in animationRestorer.restoreClosures.forEach { restoreClosure in
restoreClosure() restoreClosure()
} }
@ -18,4 +18,4 @@ public class AnimationRestorer {
animationRestorer.restoreClosures.removeAll() animationRestorer.restoreClosures.removeAll()
} }
} }
} }

View File

@ -6,10 +6,10 @@ import Macaw
extension Node: Hashable { extension Node: Hashable {
public var hashValue: Int { public var hashValue: Int {
return unsafeAddressOf(self).hashValue return Unmanaged.passUnretained(self).toOpaque().hashValue
} }
} }
public func == (lhs: Node, rhs: Node) -> Bool { public func == (lhs: Node, rhs: Node) -> Bool {
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs) return Unmanaged.passUnretained(lhs).toOpaque() == Unmanaged.passUnretained(rhs).toOpaque()
} }

View File

@ -1,7 +1,7 @@
import UIKit import UIKit
func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: (() -> ())) { func addOpacityAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: @escaping (() -> ())) {
guard let opacityAnimation = animation as? OpacityAnimation else { guard let opacityAnimation = animation as? OpacityAnimation else {
return return
} }
@ -47,13 +47,13 @@ func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animati
} }
let layer = animationCache.layerForNode(node, animation: animation) let layer = animationCache.layerForNode(node, animation: animation)
layer.addAnimation(generatedAnimation, forKey: animation.ID) layer.add(generatedAnimation, forKey: animation.ID)
animation.removeFunc = { animation.removeFunc = {
layer.removeAnimationForKey(animation.ID) layer.removeAnimation(forKey: animation.ID)
} }
} }
func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps: UInt) -> CAAnimation { func opacityAnimationByFunc(_ valueFunc: (Double) -> Double, duration: Double, fps: UInt) -> CAAnimation {
var opacityValues = [Double]() var opacityValues = [Double]()
var timeValues = [Double]() var timeValues = [Double]()
@ -61,7 +61,7 @@ func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps
let step = 1.0 / (duration * Double(fps)) let step = 1.0 / (duration * Double(fps))
var dt = 0.0 var dt = 0.0
for t in 0.0.stride(to: 1.0, by: step) { for t in stride(from: 0.0, to: 1.0, by: step) {
dt = t dt = t
if 1.0 - dt < step { if 1.0 - dt < step {
@ -75,11 +75,11 @@ func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity") let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
opacityAnimation.fillMode = kCAFillModeForwards opacityAnimation.fillMode = kCAFillModeForwards
opacityAnimation.removedOnCompletion = false opacityAnimation.isRemovedOnCompletion = false
opacityAnimation.duration = duration opacityAnimation.duration = duration
opacityAnimation.values = opacityValues opacityAnimation.values = opacityValues
opacityAnimation.keyTimes = timeValues opacityAnimation.keyTimes = timeValues as [NSNumber]?
return opacityAnimation return opacityAnimation
} }

View File

@ -1,16 +1,16 @@
import UIKit import UIKit
func caTimingFunction(easing: Easing) -> CAMediaTimingFunction { func caTimingFunction(_ easing: Easing) -> CAMediaTimingFunction {
switch easing { switch easing {
case .Ease: case .ease:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault) return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
case .Linear: case .linear:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
case .EaseIn: case .easeIn:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
case .EaseOut: case .easeOut:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
case .EaseInOut: case .easeInOut:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
} }
} }

View File

@ -1,6 +1,6 @@
import UIKit import UIKit
func addTransformAnimation(animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: (() -> ())) { func addTransformAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: @escaping (() -> ())) {
guard let transformAnimation = animation as? TransformAnimation else { guard let transformAnimation = animation as? TransformAnimation else {
return return
} }
@ -53,23 +53,23 @@ func addTransformAnimation(animation: BasicAnimation, sceneLayer: CALayer, anima
let layer = animationCache.layerForNode(node, animation: animation) let layer = animationCache.layerForNode(node, animation: animation)
layer.addAnimation(generatedAnim, forKey: animation.ID) layer.add(generatedAnim, forKey: animation.ID)
animation.removeFunc = { animation.removeFunc = {
layer.removeAnimationForKey(animation.ID) layer.removeAnimation(forKey: animation.ID)
} }
} }
func transfomToCG(transform: Transform) -> CGAffineTransform { func transfomToCG(_ transform: Transform) -> CGAffineTransform {
return CGAffineTransformMake( return CGAffineTransform(
CGFloat(transform.m11), a: CGFloat(transform.m11),
CGFloat(transform.m12), b: CGFloat(transform.m12),
CGFloat(transform.m21), c: CGFloat(transform.m21),
CGFloat(transform.m22), d: CGFloat(transform.m22),
CGFloat(transform.dx), tx: CGFloat(transform.dx),
CGFloat(transform.dy)) ty: CGFloat(transform.dy))
} }
func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, duration: Double, fps: UInt) -> CAAnimation { func transformAnimationByFunc(_ node: Node, valueFunc: (Double) -> Transform, duration: Double, fps: UInt) -> CAAnimation {
var scaleXValues = [CGFloat]() var scaleXValues = [CGFloat]()
var scaleYValues = [CGFloat]() var scaleYValues = [CGFloat]()
@ -80,7 +80,7 @@ func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, dura
let step = 1.0 / (duration * Double(fps)) let step = 1.0 / (duration * Double(fps))
var dt = 0.0 var dt = 0.0
for t in 0.0.stride(to: 1.0, by: step) { for t in stride(from: 0.0, to: 1.0, by: step) {
dt = t dt = t
if 1.0 - dt < step { if 1.0 - dt < step {
@ -112,31 +112,31 @@ func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, dura
let xAnimation = CAKeyframeAnimation(keyPath: "transform.translation.x") let xAnimation = CAKeyframeAnimation(keyPath: "transform.translation.x")
xAnimation.duration = duration xAnimation.duration = duration
xAnimation.values = xValues xAnimation.values = xValues
xAnimation.keyTimes = timeValues xAnimation.keyTimes = timeValues as [NSNumber]?
let yAnimation = CAKeyframeAnimation(keyPath: "transform.translation.y") let yAnimation = CAKeyframeAnimation(keyPath: "transform.translation.y")
yAnimation.duration = duration yAnimation.duration = duration
yAnimation.values = yValues yAnimation.values = yValues
yAnimation.keyTimes = timeValues yAnimation.keyTimes = timeValues as [NSNumber]?
let scaleXAnimation = CAKeyframeAnimation(keyPath: "transform.scale.x") let scaleXAnimation = CAKeyframeAnimation(keyPath: "transform.scale.x")
scaleXAnimation.duration = duration scaleXAnimation.duration = duration
scaleXAnimation.values = scaleXValues scaleXAnimation.values = scaleXValues
scaleXAnimation.keyTimes = timeValues scaleXAnimation.keyTimes = timeValues as [NSNumber]?
let scaleYAnimation = CAKeyframeAnimation(keyPath: "transform.scale.y") let scaleYAnimation = CAKeyframeAnimation(keyPath: "transform.scale.y")
scaleYAnimation.duration = duration scaleYAnimation.duration = duration
scaleYAnimation.values = scaleYValues scaleYAnimation.values = scaleYValues
scaleYAnimation.keyTimes = timeValues scaleYAnimation.keyTimes = timeValues as [NSNumber]?
let rotationAnimation = CAKeyframeAnimation(keyPath: "transform.rotation.z") let rotationAnimation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
rotationAnimation.duration = duration rotationAnimation.duration = duration
rotationAnimation.values = rotationValues rotationAnimation.values = rotationValues
rotationAnimation.keyTimes = timeValues rotationAnimation.keyTimes = timeValues as [NSNumber]?
let group = CAAnimationGroup() let group = CAAnimationGroup()
group.fillMode = kCAFillModeForwards group.fillMode = kCAFillModeForwards
group.removedOnCompletion = false group.isRemovedOnCompletion = false
group.animations = [scaleXAnimation, scaleYAnimation, rotationAnimation, xAnimation, yAnimation] group.animations = [scaleXAnimation, scaleYAnimation, rotationAnimation, xAnimation, yAnimation]
group.duration = duration group.duration = duration
@ -144,6 +144,6 @@ func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, dura
return group return group
} }
func fixedAngle(angle: CGFloat) -> CGFloat { func fixedAngle(_ angle: CGFloat) -> CGFloat {
return angle > -0.0000000000000000000000001 ? angle : CGFloat(2.0 * M_PI) + angle return angle > -0.0000000000000000000000001 ? angle : CGFloat(2.0 * M_PI) + angle
} }

View File

@ -8,25 +8,25 @@
import RxSwift import RxSwift
public class GroupDisposable: Disposable { open class GroupDisposable: Disposable {
private var items: [Disposable] = [] fileprivate var items: [Disposable] = []
public func dispose() { open func dispose() {
for disposable in items { for disposable in items {
disposable.dispose() disposable.dispose()
} }
items = [] items = []
} }
public func add(item: Disposable) { open func add(_ item: Disposable) {
items.append(item) items.append(item)
} }
} }
extension Disposable { extension Disposable {
public func addTo(group: GroupDisposable) { public func addTo(_ group: GroupDisposable) {
group.add(self) group.add(self)
} }
} }

View File

@ -15,7 +15,7 @@ public struct ArrayChangeEvent {
public let deletedIndices: [Int] public let deletedIndices: [Int]
public let updatedIndices: [Int] public let updatedIndices: [Int]
private init(inserted: [Int] = [], deleted: [Int] = [], updated: [Int] = []) { fileprivate init(inserted: [Int] = [], deleted: [Int] = [], updated: [Int] = []) {
assert(inserted.count + deleted.count + updated.count > 0) assert(inserted.count + deleted.count + updated.count > 0)
self.insertedIndices = inserted self.insertedIndices = inserted
self.deletedIndices = deleted self.deletedIndices = deleted
@ -23,7 +23,7 @@ public struct ArrayChangeEvent {
} }
} }
public struct ObservableArray<Element>: ArrayLiteralConvertible { public struct ObservableArray<Element>: ExpressibleByArrayLiteral {
public typealias EventType = ArrayChangeEvent public typealias EventType = ArrayChangeEvent
internal var eventSubject: PublishSubject<EventType>! internal var eventSubject: PublishSubject<EventType>!
@ -35,10 +35,10 @@ public struct ObservableArray<Element>: ArrayLiteralConvertible {
} }
public init(count:Int, repeatedValue: Element) { public init(count:Int, repeatedValue: Element) {
self.elements = Array(count: count, repeatedValue: repeatedValue) self.elements = Array(repeating: repeatedValue, count: count)
} }
public init<S : SequenceType where S.Generator.Element == Element>(_ s: S) { public init<S : Sequence>(_ s: S) where S.Iterator.Element == Element {
self.elements = Array(s) self.elements = Array(s)
} }
@ -66,7 +66,7 @@ extension ObservableArray {
return eventSubject return eventSubject
} }
private func arrayDidChange(event: EventType) { fileprivate func arrayDidChange(_ event: EventType) {
elementsSubject?.onNext(elements) elementsSubject?.onNext(elements)
eventSubject?.onNext(event) eventSubject?.onNext(event)
} }
@ -82,35 +82,35 @@ extension ObservableArray: Indexable {
} }
} }
extension ObservableArray: RangeReplaceableCollectionType { extension ObservableArray: RangeReplaceableCollection {
public var capacity: Int { public var capacity: Int {
return elements.capacity return elements.capacity
} }
public mutating func reserveCapacity(minimumCapacity: Int) { public mutating func reserveCapacity(_ minimumCapacity: Int) {
elements.reserveCapacity(minimumCapacity) elements.reserveCapacity(minimumCapacity)
} }
public mutating func append(newElement: Element) { public mutating func append(_ newElement: Element) {
elements.append(newElement) elements.append(newElement)
arrayDidChange(ArrayChangeEvent(inserted: [elements.count - 1])) arrayDidChange(ArrayChangeEvent(inserted: [elements.count - 1]))
} }
public mutating func appendContentsOf<S : SequenceType where S.Generator.Element == Element>(newElements: S) { public mutating func append<S : Sequence>(contentsOf newElements: S) where S.Iterator.Element == Element {
let end = elements.count let end = elements.count
elements.appendContentsOf(newElements) elements.append(contentsOf: newElements)
guard end != elements.count else { guard end != elements.count else {
return return
} }
arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count))) arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count)))
} }
public mutating func appendContentsOf<C : CollectionType where C.Generator.Element == Element>(newElements: C) { public mutating func appendContentsOf<C : Collection>(_ newElements: C) where C.Iterator.Element == Element {
guard !newElements.isEmpty else { guard !newElements.isEmpty else {
return return
} }
let end = elements.count let end = elements.count
elements.appendContentsOf(newElements) elements.append(contentsOf: newElements)
arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count))) arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count)))
} }
@ -120,37 +120,37 @@ extension ObservableArray: RangeReplaceableCollectionType {
return e return e
} }
public mutating func insert(newElement: Element, atIndex i: Int) { public mutating func insert(_ newElement: Element, at i: Int) {
elements.insert(newElement, atIndex: i) elements.insert(newElement, at: i)
arrayDidChange(ArrayChangeEvent(inserted: [i])) arrayDidChange(ArrayChangeEvent(inserted: [i]))
} }
public mutating func removeAtIndex(index: Int) -> Element { public mutating func remove(at index: Int) -> Element {
let e = elements.removeAtIndex(index) let e = elements.remove(at: index)
arrayDidChange(ArrayChangeEvent(deleted: [index])) arrayDidChange(ArrayChangeEvent(deleted: [index]))
return e return e
} }
public mutating func removeAll(keepCapacity: Bool = false) { public mutating func removeAll(_ keepCapacity: Bool = false) {
guard !elements.isEmpty else { guard !elements.isEmpty else {
return return
} }
let es = elements let es = elements
elements.removeAll(keepCapacity: keepCapacity) elements.removeAll(keepingCapacity: keepCapacity)
arrayDidChange(ArrayChangeEvent(deleted: Array(0..<es.count))) arrayDidChange(ArrayChangeEvent(deleted: Array(0..<es.count)))
} }
public mutating func insertContentsOf(newElements: [Element], atIndex i: Int) { public mutating func insertContentsOf(_ newElements: [Element], atIndex i: Int) {
guard !newElements.isEmpty else { guard !newElements.isEmpty else {
return return
} }
elements.insertContentsOf(newElements, at: i) elements.insert(contentsOf: newElements, at: i)
arrayDidChange(ArrayChangeEvent(inserted: Array(i..<i + newElements.count))) arrayDidChange(ArrayChangeEvent(inserted: Array(i..<i + newElements.count)))
} }
public mutating func replaceRange<C : CollectionType where C.Generator.Element == Element>(subRange: Range<Int>, with newCollection: C) { public mutating func replaceSubrange<C : Collection>(_ subRange: Range<Int>, with newCollection: C) where C.Iterator.Element == Element {
let oldCount = elements.count let oldCount = elements.count
elements.replaceRange(subRange, with: newCollection) elements.replaceSubrange(subRange, with: newCollection)
guard let first = subRange.first else { guard let first = subRange.first else {
return return
} }
@ -181,7 +181,7 @@ extension ObservableArray: CustomStringConvertible {
} }
} }
extension ObservableArray: CollectionType { extension ObservableArray: Collection {
public subscript(index: Int) -> Element { public subscript(index: Int) -> Element {
get { get {
return elements[index] return elements[index]

View File

@ -1,7 +1,7 @@
public class PanEvent { open class PanEvent {
public let dx: Double open let dx: Double
public let dy: Double open let dy: Double
init(dx: Double, dy: Double) { init(dx: Double, dy: Double) {
self.dx = dx self.dx = dx

View File

@ -1,6 +1,6 @@
public class PinchEvent { open class PinchEvent {
public let scale: Double open let scale: Double
init(scale: Double) { init(scale: Double) {
self.scale = scale self.scale = scale

View File

@ -1,6 +1,6 @@
public class RotateEvent { open class RotateEvent {
public let angle: Double open let angle: Double
init(angle: Double) { init(angle: Double) {
self.angle = angle self.angle = angle

View File

@ -1,6 +1,6 @@
public class TapEvent { open class TapEvent {
public let location: Point open let location: Point
init(location: Point) { init(location: Point) {
self.location = location self.location = location

View File

@ -1,63 +1,63 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Color: Fill { open class Color: Fill {
public let val: Int open let val: Int
public static let white: Color = Color( val: 0xFFFFFF ) open static let white: Color = Color( val: 0xFFFFFF )
public static let silver: Color = Color( val: 0xC0C0C0 ) open static let silver: Color = Color( val: 0xC0C0C0 )
public static let gray: Color = Color( val: 0x808080 ) open static let gray: Color = Color( val: 0x808080 )
public static let black: Color = Color( val: 0 ) open static let black: Color = Color( val: 0 )
public static let red: Color = Color( val: 0xFF0000 ) open static let red: Color = Color( val: 0xFF0000 )
public static let maroon: Color = Color( val: 0x800000 ) open static let maroon: Color = Color( val: 0x800000 )
public static let yellow: Color = Color( val: 0xFFFF00 ) open static let yellow: Color = Color( val: 0xFFFF00 )
public static let olive: Color = Color( val: 0x808000 ) open static let olive: Color = Color( val: 0x808000 )
public static let lime: Color = Color( val: 0x00FF00 ) open static let lime: Color = Color( val: 0x00FF00 )
public static let green: Color = Color( val: 0x008000 ) open static let green: Color = Color( val: 0x008000 )
public static let aqua: Color = Color( val: 0x00FFFF ) open static let aqua: Color = Color( val: 0x00FFFF )
public static let teal: Color = Color( val: 0x008080 ) open static let teal: Color = Color( val: 0x008080 )
public static let blue: Color = Color( val: 0x0000FF ) open static let blue: Color = Color( val: 0x0000FF )
public static let navy: Color = Color( val: 0x000080 ) open static let navy: Color = Color( val: 0x000080 )
public static let fuchsia: Color = Color( val: 0xFF00FF ) open static let fuchsia: Color = Color( val: 0xFF00FF )
public static let purple: Color = Color( val: 0x800080 ) open static let purple: Color = Color( val: 0x800080 )
public init(val: Int = 0) { public init(val: Int = 0) {
self.val = val self.val = val
} }
// GENERATED // GENERATED
public func r() -> Int { open func r() -> Int {
return ( ( val >> 16 ) & 0xff ) return ( ( val >> 16 ) & 0xff )
} }
// GENERATED // GENERATED
public func g() -> Int { open func g() -> Int {
return ( ( val >> 8 ) & 0xff ) return ( ( val >> 8 ) & 0xff )
} }
// GENERATED // GENERATED
public func b() -> Int { open func b() -> Int {
return ( val & 0xff ) return ( val & 0xff )
} }
// GENERATED // GENERATED
public func a() -> Int { open func a() -> Int {
return ( 255 - ( ( val >> 24 ) & 0xff ) ) return ( 255 - ( ( val >> 24 ) & 0xff ) )
} }
// GENERATED // GENERATED
public class func rgbt(r r: Int, g: Int, b: Int, t: Int) -> Color { open class func rgbt(r: Int, g: Int, b: Int, t: Int) -> Color {
return Color( val: ( ( ( ( ( t & 0xff ) << 24 ) | ( ( r & 0xff ) << 16 ) ) | ( ( g & 0xff ) << 8 ) ) | ( b & 0xff ) ) ) return Color( val: ( ( ( ( ( t & 0xff ) << 24 ) | ( ( r & 0xff ) << 16 ) ) | ( ( g & 0xff ) << 8 ) ) | ( b & 0xff ) ) )
} }
// GENERATED // GENERATED
public class func rgba(r r: Int, g: Int, b: Int, a: Double) -> Color { open class func rgba(r: Int, g: Int, b: Int, a: Double) -> Color {
return rgbt( r: r, g: g, b: b, t: Int( ( ( 1 - a ) * 255 ) ) ) return rgbt( r: r, g: g, b: b, t: Int( ( ( 1 - a ) * 255 ) ) )
} }
// GENERATED // GENERATED
public class func rgb(r r: Int, g: Int, b: Int) -> Color { open class func rgb(r: Int, g: Int, b: Int) -> Color {
return rgbt( r: r, g: g, b: b, t: 0 ) return rgbt( r: r, g: g, b: b, t: 0 )
} }

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Drawable { open class Drawable {
public let visible: Bool open let visible: Bool
public let tag: [String] open let tag: [String]
public init(visible: Bool = true, tag: [String] = []) { public init(visible: Bool = true, tag: [String] = []) {
self.visible = visible self.visible = visible

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class DropShadow: Effect { open class DropShadow: Effect {
public let radius: Double open let radius: Double
public let offset: Point open let offset: Point
public let color: Color open let color: Color
public let input: Effect? open let input: Effect?
public init(radius: Double = 0, offset: Point = Point.origin, color: Color = Color.black, input: Effect? = nil) { public init(radius: Double = 0, offset: Point = Point.origin, color: Color = Color.black, input: Effect? = nil) {
self.radius = radius self.radius = radius

View File

@ -1,7 +1,7 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Effect { open class Effect {
public init() { public init() {
} }

View File

@ -1,7 +1,7 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Fill { open class Fill {
public init() { public init() {
} }

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Font { open class Font {
public let name: String open let name: String
public let size: Int open let size: Int
public init(name: String = "Serif", size: Int = 12) { public init(name: String = "Serif", size: Int = 12) {
self.name = name self.name = name

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class GaussianBlur: Effect { open class GaussianBlur: Effect {
public let radius: Double open let radius: Double
public let input: Effect? open let input: Effect?
public init(radius: Double = 0, input: Effect? = nil) { public init(radius: Double = 0, input: Effect? = nil) {
self.radius = radius self.radius = radius

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Gradient: Fill { open class Gradient: Fill {
public let userSpace: Bool open let userSpace: Bool
public let stops: [Stop] open let stops: [Stop]
public init(userSpace: Bool = false, stops: [Stop] = []) { public init(userSpace: Bool = false, stops: [Stop] = []) {
self.userSpace = userSpace self.userSpace = userSpace

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class LinearGradient: Gradient { open class LinearGradient: Gradient {
public let x1: Double open let x1: Double
public let y1: Double open let y1: Double
public let x2: Double open let x2: Double
public let y2: Double open let y2: Double
public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0, userSpace: Bool = false, stops: [Stop] = []) { public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0, userSpace: Bool = false, stops: [Stop] = []) {
self.x1 = x1 self.x1 = x1

View File

@ -1,13 +1,13 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class RadialGradient: Gradient { open class RadialGradient: Gradient {
public let cx: Double open let cx: Double
public let cy: Double open let cy: Double
public let fx: Double open let fx: Double
public let fy: Double open let fy: Double
public let r: Double open let r: Double
public init(cx: Double = 0.5, cy: Double = 0.5, fx: Double = 0.5, fy: Double = 0.5, r: Double = 0.5, userSpace: Bool = false, stops: [Stop] = []) { public init(cx: Double = 0.5, cy: Double = 0.5, fx: Double = 0.5, fy: Double = 0.5, r: Double = 0.5, userSpace: Bool = false, stops: [Stop] = []) {
self.cx = cx self.cx = cx

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Stop { open class Stop {
public let offset: Double open let offset: Double
public let color: Color open let color: Color
public init(offset: Double = 0, color: Color) { public init(offset: Double = 0, color: Color) {
self.offset = offset self.offset = offset

View File

@ -1,13 +1,13 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Stroke { open class Stroke {
public let fill: Fill open let fill: Fill
public let width: Double open let width: Double
public let cap: LineCap open let cap: LineCap
public let join: LineJoin open let join: LineJoin
public let dashes: [Double] open let dashes: [Double]
public init(fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) { public init(fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) {
self.fill = fill self.fill = fill

View File

@ -1,11 +1,11 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Arc: Locus { open class Arc: Locus {
public let ellipse: Ellipse open let ellipse: Ellipse
public let shift: Double open let shift: Double
public let extent: Double open let extent: Double
public init(ellipse: Ellipse, shift: Double = 0, extent: Double = 0) { public init(ellipse: Ellipse, shift: Double = 0, extent: Double = 0) {
self.ellipse = ellipse self.ellipse = ellipse

View File

@ -1,11 +1,11 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Circle: Locus { open class Circle: Locus {
public let cx: Double open let cx: Double
public let cy: Double open let cy: Double
public let r: Double open let r: Double
public init(cx: Double = 0, cy: Double = 0, r: Double = 0) { public init(cx: Double = 0, cy: Double = 0, r: Double = 0) {
self.cx = cx self.cx = cx
@ -14,7 +14,7 @@ public class Circle: Locus {
} }
// GENERATED NOT // GENERATED NOT
public func arc(shift shift: Double, extent: Double) -> Arc { open func arc(shift: Double, extent: Double) -> Arc {
return Arc(ellipse: Ellipse(cx: cx, cy: cy, rx: r, ry: r), shift: shift, extent: extent) return Arc(ellipse: Ellipse(cx: cx, cy: cy, rx: r, ry: r), shift: shift, extent: extent)
} }

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Ellipse: Locus { open class Ellipse: Locus {
public let cx: Double open let cx: Double
public let cy: Double open let cy: Double
public let rx: Double open let rx: Double
public let ry: Double open let ry: Double
public init(cx: Double = 0, cy: Double = 0, rx: Double = 0, ry: Double = 0) { public init(cx: Double = 0, cy: Double = 0, rx: Double = 0, ry: Double = 0) {
self.cx = cx self.cx = cx
@ -16,7 +16,7 @@ public class Ellipse: Locus {
} }
// GENERATED NOT // GENERATED NOT
public func arc(shift shift: Double, extent: Double) -> Arc { open func arc(shift: Double, extent: Double) -> Arc {
return Arc(ellipse: self, shift: shift, extent: extent) return Arc(ellipse: self, shift: shift, extent: extent)
} }

View File

@ -1,6 +1,6 @@
public class GeomUtils { open class GeomUtils {
public class func concat(t1 t1: Transform, t2: Transform) -> Transform { open class func concat(t1: Transform, t2: Transform) -> Transform {
let nm11 = t2.m11 * t1.m11 + t2.m12 * t1.m21 let nm11 = t2.m11 * t1.m11 + t2.m12 * t1.m21
let nm21 = t2.m21 * t1.m11 + t2.m22 * t1.m21 let nm21 = t2.m21 * t1.m11 + t2.m22 * t1.m21
let ndx = t2.dx * t1.m11 + t2.dy * t1.m21 + t1.dx let ndx = t2.dx * t1.m11 + t2.dy * t1.m21 + t1.dx
@ -10,7 +10,7 @@ public class GeomUtils {
return Transform(m11: nm11, m12: nm12, m21: nm21, m22: nm22, dx: ndx, dy: ndy) return Transform(m11: nm11, m12: nm12, m21: nm21, m22: nm22, dx: ndx, dy: ndy)
} }
public class func centerRotation(node node: Node, place: Transform, angle: Double) -> Transform { open class func centerRotation(node: Node, place: Transform, angle: Double) -> Transform {
guard let bounds = node.bounds() else { guard let bounds = node.bounds() else {
return Transform() return Transform()
} }

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Insets { open class Insets {
public let top: Double open let top: Double
public let right: Double open let right: Double
public let bottom: Double open let bottom: Double
public let left: Double open let left: Double
public init(top: Double = 0, right: Double = 0, bottom: Double = 0, left: Double = 0) { public init(top: Double = 0, right: Double = 0, bottom: Double = 0, left: Double = 0) {
self.top = top self.top = top

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Line: Locus { open class Line: Locus {
public let x1: Double open let x1: Double
public let y1: Double open let y1: Double
public let x2: Double open let x2: Double
public let y2: Double open let y2: Double
public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0) { public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0) {
self.x1 = x1 self.x1 = x1

View File

@ -1,28 +1,28 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Locus { open class Locus {
public init() { public init() {
} }
// GENERATED NOT // GENERATED NOT
public func bounds() -> Rect { open func bounds() -> Rect {
return Rect() return Rect()
} }
// GENERATED NOT // GENERATED NOT
public func stroke(with with: Stroke) -> Shape { open func stroke(with: Stroke) -> Shape {
return Shape(form: self, stroke: with) return Shape(form: self, stroke: with)
} }
// GENERATED NOT // GENERATED NOT
public func fill(with with: Fill) -> Shape { open func fill(with: Fill) -> Shape {
return Shape(form: self, fill: with) return Shape(form: self, fill: with)
} }
// GENERATED NOT // GENERATED NOT
public func stroke(fill fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) -> Shape { open func stroke(fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) -> Shape {
return Shape(form: self, stroke: Stroke(fill: fill, width: width, cap: cap, join: join, dashes: dashes)) return Shape(form: self, stroke: Stroke(fill: fill, width: width, cap: cap, join: join, dashes: dashes))
} }

View File

@ -1,7 +1,7 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class MoveTo: PathBuilder { open class MoveTo: PathBuilder {
// GENERATED NOT // GENERATED NOT
public init(x: Double, y: Double) { public init(x: Double, y: Double) {

View File

@ -1,9 +1,9 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Path: Locus { open class Path: Locus {
public let segments: [PathSegment] open let segments: [PathSegment]
public init(segments: [PathSegment] = []) { public init(segments: [PathSegment] = []) {
self.segments = segments self.segments = segments

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class PathBuilder { open class PathBuilder {
public let segment: PathSegment open let segment: PathSegment
public let rest: PathBuilder? open let rest: PathBuilder?
public init(segment: PathSegment, rest: PathBuilder? = nil) { public init(segment: PathSegment, rest: PathBuilder? = nil) {
self.segment = segment self.segment = segment
@ -12,143 +12,143 @@ public class PathBuilder {
} }
// GENERATED NOT // GENERATED NOT
public func moveTo(x x: Double, y: Double) -> PathBuilder { open func moveTo(x: Double, y: Double) -> PathBuilder {
return M(x, y) return M(x, y)
} }
// GENERATED NOT // GENERATED NOT
public func lineTo(x x: Double, y: Double) -> PathBuilder { open func lineTo(x: Double, y: Double) -> PathBuilder {
return L(x, y) return L(x, y)
} }
// GENERATED NOT // GENERATED NOT
public func cubicTo(x1 x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) -> PathBuilder { open func cubicTo(x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) -> PathBuilder {
return C(x1, y1, x2, y2, x, y) return C(x1, y1, x2, y2, x, y)
} }
// GENERATED NOT // GENERATED NOT
public func quadraticTo(x1 x1: Double, y1: Double, x: Double, y: Double) -> PathBuilder { open func quadraticTo(x1: Double, y1: Double, x: Double, y: Double) -> PathBuilder {
return Q(x1, y1, x, y) return Q(x1, y1, x, y)
} }
// GENERATED NOT // GENERATED NOT
public func arcTo(rx rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) -> PathBuilder { open func arcTo(rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) -> PathBuilder {
return A(rx, ry, angle, largeArc, sweep, x, y) return A(rx, ry, angle, largeArc, sweep, x, y)
} }
// GENERATED NOT // GENERATED NOT
public func close() -> PathBuilder { open func close() -> PathBuilder {
return Z() return Z()
} }
// GENERATED NOT // GENERATED NOT
public func m(x: Double, _ y: Double) -> PathBuilder { open func m(_ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .m, data: [x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .m, data: [x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func M(x: Double, _ y: Double) -> PathBuilder { open func M(_ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .M, data: [x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .M, data: [x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func l(x: Double, _ y: Double) -> PathBuilder { open func l(_ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .l, data: [x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .l, data: [x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func L(x: Double, _ y: Double) -> PathBuilder { open func L(_ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .L, data: [x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .L, data: [x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func h(x: Double) -> PathBuilder { open func h(_ x: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .h, data: [x]), rest: self) return PathBuilder(segment: PathSegment(type: .h, data: [x]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func H(x: Double) -> PathBuilder { open func H(_ x: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .H, data: [x]), rest: self) return PathBuilder(segment: PathSegment(type: .H, data: [x]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func v(y: Double) -> PathBuilder { open func v(_ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .v, data: [y]), rest: self) return PathBuilder(segment: PathSegment(type: .v, data: [y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func V(y: Double) -> PathBuilder { open func V(_ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .V, data: [y]), rest: self) return PathBuilder(segment: PathSegment(type: .V, data: [y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func c(x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder { open func c(_ x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .c, data: [x1, y1, x2, y2, x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .c, data: [x1, y1, x2, y2, x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func C(x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder { open func C(_ x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .C, data: [x1, y1, x2, y2, x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .C, data: [x1, y1, x2, y2, x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func s(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder { open func s(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .s, data: [x2, y2, x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .s, data: [x2, y2, x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func S(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder { open func S(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .S, data: [x2, y2, x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .S, data: [x2, y2, x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func q(x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder { open func q(_ x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .q, data: [x1, y1, x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .q, data: [x1, y1, x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func Q(x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder { open func Q(_ x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .Q, data: [x1, y1, x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .Q, data: [x1, y1, x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func t(x: Double, _ y: Double) -> PathBuilder { open func t(_ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .t, data: [x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .t, data: [x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func T(x: Double, _ y: Double) -> PathBuilder { open func T(_ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .T, data: [x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .T, data: [x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func a(rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder { open func a(_ rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .a, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .a, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func A(rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder { open func A(_ rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .A, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self) return PathBuilder(segment: PathSegment(type: .A, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func Z() -> PathBuilder { open func Z() -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .Z), rest: self) return PathBuilder(segment: PathSegment(type: .z), rest: self)
} }
// GENERATED NOT // GENERATED NOT
public func build() -> Path { open func build() -> Path {
var segments : [PathSegment] = [] var segments : [PathSegment] = []
var builder : PathBuilder? = self var builder : PathBuilder? = self
while(builder != nil) { while(builder != nil) {
segments.append(builder!.segment) segments.append(builder!.segment)
builder = builder!.rest builder = builder!.rest
} }
return Path(segments: segments.reverse()) return Path(segments: segments.reversed())
} }
// GENERATED NOT // GENERATED NOT
private func boolsToNum(largeArc: Bool, sweep: Bool) -> Double { fileprivate func boolsToNum(_ largeArc: Bool, sweep: Bool) -> Double {
return (largeArc ? 1 : 0) + (sweep ? 1 : 0) * 2; return (largeArc ? 1 : 0) + (sweep ? 1 : 0) * 2;
} }

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class PathSegment { open class PathSegment {
public let type: PathSegmentType open let type: PathSegmentType
public let data: [Double] open let data: [Double]
public init(type: PathSegmentType = .M, data: [Double] = []) { public init(type: PathSegmentType = .M, data: [Double] = []) {
self.type = type self.type = type
@ -12,7 +12,7 @@ public class PathSegment {
} }
// GENERATED NOT // GENERATED NOT
public func isAbsolute() -> Bool { open func isAbsolute() -> Bool {
switch type { switch type {
case .M, .L, .H, .V, .C, .S, .Q, .T, .A: case .M, .L, .H, .V, .C, .S, .Q, .T, .A:
return true return true

View File

@ -4,7 +4,7 @@ public enum PathSegmentType {
case C case C
case Q case Q
case A case A
case Z case z
case H case H
case V case V
case S case S

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Point: Locus { open class Point: Locus {
public let x: Double open let x: Double
public let y: Double open let y: Double
public static let origin: Point = Point( x: 0, y: 0 ) open static let origin: Point = Point( x: 0, y: 0 )
public init(x: Double = 0, y: Double = 0) { public init(x: Double = 0, y: Double = 0) {
self.x = x self.x = x
@ -14,7 +14,7 @@ public class Point: Locus {
} }
// GENERATED NOT // GENERATED NOT
public func add(point: Point) -> Point { open func add(_ point: Point) -> Point {
return Point( return Point(
x: self.x + point.x, x: self.x + point.x,
y: self.y + point.y) y: self.y + point.y)

View File

@ -1,9 +1,9 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Polygon: Locus { open class Polygon: Locus {
public let points: [Double] open let points: [Double]
public init(points: [Double] = []) { public init(points: [Double] = []) {
self.points = points self.points = points

View File

@ -1,9 +1,9 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Polyline: Locus { open class Polyline: Locus {
public let points: [Double] open let points: [Double]
public init(points: [Double] = []) { public init(points: [Double] = []) {
self.points = points self.points = points

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Rect: Locus { open class Rect: Locus {
public let x: Double open let x: Double
public let y: Double open let y: Double
public let w: Double open let w: Double
public let h: Double open let h: Double
public init(x: Double = 0, y: Double = 0, w: Double = 0, h: Double = 0) { public init(x: Double = 0, y: Double = 0, w: Double = 0, h: Double = 0) {
self.x = x self.x = x
@ -16,12 +16,12 @@ public class Rect: Locus {
} }
// GENERATED NOT // GENERATED NOT
public func round(rx rx: Double, ry: Double) -> RoundRect { open func round(rx: Double, ry: Double) -> RoundRect {
return RoundRect(rect: self, rx: rx, ry: ry) return RoundRect(rect: self, rx: rx, ry: ry)
} }
// GENERATED NOT // GENERATED NOT
public func contains(locus locus: Locus) -> Bool { open func contains(locus: Locus) -> Bool {
return false return false
} }
@ -31,7 +31,7 @@ public class Rect: Locus {
} }
// GENERATED NOT // GENERATED NOT
public func move(offset offset: Point) -> Rect { open func move(offset: Point) -> Rect {
return Rect( return Rect(
x: self.x + offset.x, x: self.x + offset.x,
y: self.y + offset.y, y: self.y + offset.y,
@ -40,7 +40,7 @@ public class Rect: Locus {
} }
// GENERATED NOT // GENERATED NOT
public func union(rect rect: Rect) -> Rect { open func union(rect: Rect) -> Rect {
return Rect( return Rect(
x: min(self.x, rect.x), x: min(self.x, rect.x),
y: min(self.y, rect.y), y: min(self.y, rect.y),

View File

@ -1,11 +1,11 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class RoundRect: Locus { open class RoundRect: Locus {
public let rect: Rect open let rect: Rect
public let rx: Double open let rx: Double
public let ry: Double open let ry: Double
public init(rect: Rect, rx: Double = 0, ry: Double = 0) { public init(rect: Rect, rx: Double = 0, ry: Double = 0) {
self.rect = rect self.rect = rect

View File

@ -1,10 +1,10 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Size { open class Size {
public let w: Double open let w: Double
public let h: Double open let h: Double
public init(w: Double = 0, h: Double = 0) { public init(w: Double = 0, h: Double = 0) {
self.w = w self.w = w

View File

@ -22,57 +22,57 @@ public final class Transform {
} }
// GENERATED NOT // GENERATED NOT
public func move(dx dx: Double, dy: Double) -> Transform { public func move(dx: Double, dy: Double) -> Transform {
return Transform(m11: m11, m12: m12, m21: m21, m22: m22, return Transform(m11: m11, m12: m12, m21: m21, m22: m22,
dx: dx * m11 + dy * m21 + self.dx, dy: dx * m12 + dy * m22 + self.dy) dx: dx * m11 + dy * m21 + self.dx, dy: dx * m12 + dy * m22 + self.dy)
} }
// GENERATED NOT // GENERATED NOT
public func scale(sx sx: Double, sy: Double) -> Transform { public func scale(sx: Double, sy: Double) -> Transform {
return Transform(m11: m11 * sx, m12: m12 * sx, m21: m21 * sy, m22: m22 * sy, dx: dx, dy: dy) return Transform(m11: m11 * sx, m12: m12 * sx, m21: m21 * sy, m22: m22 * sy, dx: dx, dy: dy)
} }
// GENERATED NOT // GENERATED NOT
public func shear(shx shx: Double, shy: Double) -> Transform { public func shear(shx: Double, shy: Double) -> Transform {
return Transform(m11: m11 + m21 * shy, m12: m12 + m22 * shy, return Transform(m11: m11 + m21 * shy, m12: m12 + m22 * shy,
m21: m11 * shx + m21, m22: m12 * shx + m22, dx: dx, dy: dy) m21: m11 * shx + m21, m22: m12 * shx + m22, dx: dx, dy: dy)
} }
// GENERATED NOT // GENERATED NOT
public func rotate(angle angle: Double) -> Transform { public func rotate(angle: Double) -> Transform {
let asin = sin(angle); let acos = cos(angle) let asin = sin(angle); let acos = cos(angle)
return Transform(m11: acos * m11 + asin * m21, m12: acos * m12 + asin * m22, return Transform(m11: acos * m11 + asin * m21, m12: acos * m12 + asin * m22,
m21: -asin * m11 + acos * m21, m22: -asin * m12 + acos * m22, dx: dx, dy: dy) m21: -asin * m11 + acos * m21, m22: -asin * m12 + acos * m22, dx: dx, dy: dy)
} }
// GENERATED NOT // GENERATED NOT
public func rotate(angle angle: Double, x: Double, y: Double) -> Transform { public func rotate(angle: Double, x: Double, y: Double) -> Transform {
return move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y) return move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y)
} }
// GENERATED // GENERATED
public class func move(dx dx: Double, dy: Double) -> Transform { public class func move(dx: Double, dy: Double) -> Transform {
return Transform(dx: dx, dy: dy) return Transform(dx: dx, dy: dy)
} }
// GENERATED // GENERATED
public class func scale(sx sx: Double, sy: Double) -> Transform { public class func scale(sx: Double, sy: Double) -> Transform {
return Transform(m11: sx, m22: sy) return Transform(m11: sx, m22: sy)
} }
// GENERATED // GENERATED
public class func shear(shx shx: Double, shy: Double) -> Transform { public class func shear(shx: Double, shy: Double) -> Transform {
return Transform(m12: shy, m21: shx) return Transform(m12: shy, m21: shx)
} }
// GENERATED NOT // GENERATED NOT
public class func rotate(angle angle: Double) -> Transform { public class func rotate(angle: Double) -> Transform {
let asin = sin(angle); let acos = cos(angle) let asin = sin(angle); let acos = cos(angle)
return Transform(m11: acos, m12: asin, m21: -asin, m22: acos) return Transform(m11: acos, m12: asin, m21: -asin, m22: acos)
} }
// GENERATED NOT // GENERATED NOT
public class func rotate(angle angle: Double, x: Double, y: Double) -> Transform { public class func rotate(angle: Double, x: Double, y: Double) -> Transform {
return Transform.move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y) return Transform.move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y)
} }

View File

@ -1,9 +1,9 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Group: Node { open class Group: Node {
public var contents: ObservableArray<Node> open var contents: ObservableArray<Node>
public init(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) { public init(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
self.contents = ObservableArray<Node>(array: contents) self.contents = ObservableArray<Node>(array: contents)
@ -22,12 +22,12 @@ public class Group: Node {
override internal func bounds() -> Rect? { override internal func bounds() -> Rect? {
guard let firstPos = contents.first?.place else { guard let firstPos = contents.first?.place else {
return .None return .none
} }
guard var union = contents.first?.bounds()?.applyTransform(firstPos) else { guard var union = contents.first?.bounds()?.applyTransform(firstPos) else {
return .None return .none
} }
contents.forEach { node in contents.forEach { node in

View File

@ -1,40 +1,40 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Image: Node { open class Image: Node {
public let srcVar: Variable<String> open let srcVar: Variable<String>
public var src: String { open var src: String {
get { return srcVar.value } get { return srcVar.value }
set(val) { srcVar.value = val } set(val) { srcVar.value = val }
} }
public let xAlignVar: Variable<Align> open let xAlignVar: Variable<Align>
public var xAlign: Align { open var xAlign: Align {
get { return xAlignVar.value } get { return xAlignVar.value }
set(val) { xAlignVar.value = val } set(val) { xAlignVar.value = val }
} }
public let yAlignVar: Variable<Align> open let yAlignVar: Variable<Align>
public var yAlign: Align { open var yAlign: Align {
get { return yAlignVar.value } get { return yAlignVar.value }
set(val) { yAlignVar.value = val } set(val) { yAlignVar.value = val }
} }
public let aspectRatioVar: Variable<AspectRatio> open let aspectRatioVar: Variable<AspectRatio>
public var aspectRatio: AspectRatio { open var aspectRatio: AspectRatio {
get { return aspectRatioVar.value } get { return aspectRatioVar.value }
set(val) { aspectRatioVar.value = val } set(val) { aspectRatioVar.value = val }
} }
public let wVar: Variable<Int> open let wVar: Variable<Int>
public var w: Int { open var w: Int {
get { return wVar.value } get { return wVar.value }
set(val) { wVar.value = val } set(val) { wVar.value = val }
} }
public let hVar: Variable<Int> open let hVar: Variable<Int>
public var h: Int { open var h: Int {
get { return hVar.value } get { return hVar.value }
set(val) { hVar.value = val } set(val) { hVar.value = val }
} }

View File

@ -1,34 +1,34 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Node: Drawable { open class Node: Drawable {
public let placeVar: AnimatableVariable<Transform> open let placeVar: AnimatableVariable<Transform>
public var place: Transform { open var place: Transform {
get { return placeVar.value } get { return placeVar.value }
set(val) { placeVar.value = val } set(val) { placeVar.value = val }
} }
public let opaqueVar: Variable<Bool> open let opaqueVar: Variable<Bool>
public var opaque: Bool { open var opaque: Bool {
get { return opaqueVar.value } get { return opaqueVar.value }
set(val) { opaqueVar.value = val } set(val) { opaqueVar.value = val }
} }
public let opacityVar: AnimatableVariable<Double> open let opacityVar: AnimatableVariable<Double>
public var opacity: Double { open var opacity: Double {
get { return opacityVar.value } get { return opacityVar.value }
set(val) { opacityVar.value = val } set(val) { opacityVar.value = val }
} }
public let clipVar: Variable<Locus?> open let clipVar: Variable<Locus?>
public var clip: Locus? { open var clip: Locus? {
get { return clipVar.value } get { return clipVar.value }
set(val) { clipVar.value = val } set(val) { clipVar.value = val }
} }
public let effectVar: Variable<Effect?> open let effectVar: Variable<Effect?>
public var effect: Effect? { open var effect: Effect? {
get { return effectVar.value } get { return effectVar.value }
set(val) { effectVar.value = val } set(val) { effectVar.value = val }
} }

View File

@ -1,30 +1,30 @@
import Foundation import Foundation
import RxSwift import RxSwift
public class Shape: Node { open class Shape: Node {
public let formVar: Variable<Locus> open let formVar: Variable<Locus>
public var form: Locus { open var form: Locus {
get { return formVar.value } get { return formVar.value }
set(val) { formVar.value = val } set(val) { formVar.value = val }
} }
public let fillVar: Variable<Fill?> open let fillVar: Variable<Fill?>
public var fill: Fill? { open var fill: Fill? {
get { return fillVar.value } get { return fillVar.value }
set(val) { fillVar.value = val } set(val) { fillVar.value = val }
} }
public let strokeVar: Variable<Stroke?> open let strokeVar: Variable<Stroke?>
public var stroke: Stroke? { open var stroke: Stroke? {
get { return strokeVar.value } get { return strokeVar.value }
set(val) { strokeVar.value = val } set(val) { strokeVar.value = val }
} }
public let onTap = PublishSubject<TapEvent>() open let onTap = PublishSubject<TapEvent>()
public let onPan = PublishSubject<PanEvent>() open let onPan = PublishSubject<PanEvent>()
public let onRotate = PublishSubject<RotateEvent>() open let onRotate = PublishSubject<RotateEvent>()
public let onPinch = PublishSubject<PinchEvent>() open let onPinch = PublishSubject<PinchEvent>()
public init(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) { public init(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
self.formVar = Variable<Locus>(form) self.formVar = Variable<Locus>(form)

View File

@ -1,34 +1,34 @@
import UIKit import UIKit
import RxSwift import RxSwift
public class Text: Node { open class Text: Node {
public let textVar: Variable<String> open let textVar: Variable<String>
public var text: String { open var text: String {
get { return textVar.value } get { return textVar.value }
set(val) { textVar.value = val } set(val) { textVar.value = val }
} }
public let fontVar: Variable<Font?> open let fontVar: Variable<Font?>
public var font: Font? { open var font: Font? {
get { return fontVar.value } get { return fontVar.value }
set(val) { fontVar.value = val } set(val) { fontVar.value = val }
} }
public let fillVar: Variable<Fill> open let fillVar: Variable<Fill>
public var fill: Fill { open var fill: Fill {
get { return fillVar.value } get { return fillVar.value }
set(val) { fillVar.value = val } set(val) { fillVar.value = val }
} }
public let alignVar: Variable<Align> open let alignVar: Variable<Align>
public var align: Align { open var align: Align {
get { return alignVar.value } get { return alignVar.value }
set(val) { alignVar.value = val } set(val) { alignVar.value = val }
} }
public let baselineVar: Variable<Baseline> open let baselineVar: Variable<Baseline>
public var baseline: Baseline { open var baseline: Baseline {
get { return baselineVar.value } get { return baselineVar.value }
set(val) { baselineVar.value = val } set(val) { baselineVar.value = val }
} }
@ -57,14 +57,14 @@ public class Text: Node {
if let customFont = UIFont(name: f.name, size: CGFloat(f.size)) { if let customFont = UIFont(name: f.name, size: CGFloat(f.size)) {
font = customFont font = customFont
} else { } else {
font = UIFont.systemFontOfSize(CGFloat(f.size)) font = UIFont.systemFont(ofSize: CGFloat(f.size))
} }
} else { } else {
font = UIFont.systemFontOfSize(UIFont.systemFontSize()) font = UIFont.systemFont(ofSize: UIFont.systemFontSize)
} }
var stringAttributes: [String: AnyObject] = [:] var stringAttributes: [String: AnyObject] = [:]
stringAttributes[NSFontAttributeName] = font stringAttributes[NSFontAttributeName] = font
let size = (text as NSString).sizeWithAttributes(stringAttributes) let size = (text as NSString).size(attributes: stringAttributes)
if (self.baseline == Baseline.bottom) { if (self.baseline == Baseline.bottom) {
return Rect(x: 0, y: -Double(size.height), w: Double(size.width), h: Double(size.height)) return Rect(x: 0, y: -Double(size.height), w: Double(size.width), h: Double(size.height))
} }

View File

@ -6,7 +6,7 @@ class GroupRenderer: NodeRenderer {
let group: Group let group: Group
private var renderers: [NodeRenderer] = [] fileprivate var renderers: [NodeRenderer] = []
init(group: Group, ctx: RenderContext, animationCache: AnimationCache) { init(group: Group, ctx: RenderContext, animationCache: AnimationCache) {
self.group = group self.group = group
@ -24,27 +24,27 @@ class GroupRenderer: NodeRenderer {
return group return group
} }
override func doRender(force: Bool, opacity: Double) { override func doRender(_ force: Bool, opacity: Double) {
renderers.forEach { renderer in renderers.forEach { renderer in
CGContextSaveGState(ctx.cgContext!) ctx.cgContext!.saveGState()
CGContextConcatCTM(ctx.cgContext!, RenderUtils.mapTransform(renderer.node().place)) ctx.cgContext!.concatenate(RenderUtils.mapTransform(renderer.node().place))
setClip(renderer.node()) setClip(renderer.node())
renderer.render(force, opacity: renderer.node().opacity * opacity) renderer.render(force, opacity: renderer.node().opacity * opacity)
CGContextRestoreGState(ctx.cgContext!) ctx.cgContext!.restoreGState()
} }
} }
override func detectTouches(location: CGPoint) -> [Shape] { override func detectTouches(_ location: CGPoint) -> [Shape] {
var touchedShapes = [Shape]() var touchedShapes = [Shape]()
renderers.forEach { renderer in renderers.forEach { renderer in
if let inverted = renderer.node().place.invert() { if let inverted = renderer.node().place.invert() {
CGContextSaveGState(ctx.cgContext!) ctx.cgContext!.saveGState()
CGContextConcatCTM(ctx.cgContext!, RenderUtils.mapTransform(renderer.node().place)) ctx.cgContext!.concatenate(RenderUtils.mapTransform(renderer.node().place))
let translatedLocation = CGPointApplyAffineTransform(location, RenderUtils.mapTransform(inverted)) let translatedLocation = location.applying(RenderUtils.mapTransform(inverted))
setClip(renderer.node()) setClip(renderer.node())
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y) let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
touchedShapes.appendContentsOf(renderer.detectTouches(offsetLocation)) touchedShapes.append(contentsOf: renderer.detectTouches(offsetLocation))
CGContextRestoreGState(ctx.cgContext!) ctx.cgContext!.restoreGState()
} }
} }
@ -59,20 +59,20 @@ class GroupRenderer: NodeRenderer {
// TODO: extract to NodeRenderer // TODO: extract to NodeRenderer
// TODO: path support // TODO: path support
func setClip(node: Node) { func setClip(_ node: Node) {
if let rect = node.clip as? Rect { if let rect = node.clip as? Rect {
CGContextClipToRect(ctx.cgContext!, CGRect(x: rect.x, y: rect.y, width: rect.w, height: rect.h)) ctx.cgContext!.clip(to: CGRect(x: rect.x, y: rect.y, width: rect.w, height: rect.h))
} }
} }
private func updateRenderers() { fileprivate func updateRenderers() {
var nodeToRenderer: [Node: NodeRenderer] = [:] var nodeToRenderer: [Node: NodeRenderer] = [:]
for renderer in renderers { for renderer in renderers {
nodeToRenderer[renderer.node()] = renderer nodeToRenderer[renderer.node()] = renderer
} }
self.renderers = [] self.renderers = []
for node in group.contents { for node in group.contents {
if let renderer = nodeToRenderer.removeValueForKey(node) { if let renderer = nodeToRenderer.removeValue(forKey: node) {
self.renderers.append(renderer) self.renderers.append(renderer)
} else { } else {
self.renderers.append(RenderUtils.createNodeRenderer(node, context: ctx, animationCache: animationCache)) self.renderers.append(RenderUtils.createNodeRenderer(node, context: ctx, animationCache: animationCache))

View File

@ -25,14 +25,14 @@ class ImageRenderer: NodeRenderer {
observe(image.hVar) observe(image.hVar)
} }
override func doRender(force: Bool, opacity: Double) { override func doRender(_ force: Bool, opacity: Double) {
if let uiimage = UIImage(named: image.src) { if let uiimage = UIImage(named: image.src) {
let imageSize = uiimage.size let imageSize = uiimage.size
var w = CGFloat(image.w) var w = CGFloat(image.w)
var h = CGFloat(image.h) var h = CGFloat(image.h)
var rect: CGRect var rect: CGRect
if ((w == 0 || w == imageSize.width) && (h == 0 || h == imageSize.height)) { if ((w == 0 || w == imageSize.width) && (h == 0 || h == imageSize.height)) {
rect = CGRectMake(0, 0, imageSize.width, imageSize.height) rect = CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height)
} else { } else {
if (w == 0) { if (w == 0) {
w = imageSize.width * h / imageSize.height w = imageSize.width * h / imageSize.height
@ -44,25 +44,25 @@ class ImageRenderer: NodeRenderer {
rect = calculateMeetAspectRatio(image, size: imageSize) rect = calculateMeetAspectRatio(image, size: imageSize)
case AspectRatio.slice: case AspectRatio.slice:
rect = calculateSliceAspectRatio(image, size: imageSize) rect = calculateSliceAspectRatio(image, size: imageSize)
CGContextClipToRect(ctx.cgContext!, CGRectMake(0, 0, w, h)) ctx.cgContext!.clip(to: CGRect(x: 0, y: 0, width: w, height: h))
default: default:
rect = CGRectMake(0, 0, w, h) rect = CGRect(x: 0, y: 0, width: w, height: h)
} }
} }
CGContextScaleCTM(ctx.cgContext!, 1.0, -1.0) ctx.cgContext!.scaleBy(x: 1.0, y: -1.0)
CGContextTranslateCTM(ctx.cgContext!, 0.0, -1.0 * rect.height) ctx.cgContext!.translateBy(x: 0.0, y: -1.0 * rect.height)
CGContextSetAlpha(ctx.cgContext!, CGFloat(opacity)) ctx.cgContext!.setAlpha(CGFloat(opacity))
CGContextDrawImage(ctx.cgContext!, rect, uiimage.CGImage!) ctx.cgContext!.draw(uiimage.cgImage!, in: rect)
} }
} }
override func detectTouches(location: CGPoint) -> [Shape] { override func detectTouches(_ location: CGPoint) -> [Shape] {
return [] return []
} }
private func calculateMeetAspectRatio(image: Image, size: CGSize) -> CGRect { fileprivate func calculateMeetAspectRatio(_ image: Image, size: CGSize) -> CGRect {
let w = CGFloat(image.w) let w = CGFloat(image.w)
let h = CGFloat(image.h) let h = CGFloat(image.h)
// destination and source aspect ratios // destination and source aspect ratios
@ -97,10 +97,10 @@ class ImageRenderer: NodeRenderer {
case Align.max: case Align.max:
destY = h - resultH destY = h - resultH
} }
return CGRectMake(destX, destY, resultW, resultH) return CGRect(x: destX, y: destY, width: resultW, height: resultH)
} }
private func calculateSliceAspectRatio(image: Image, size: CGSize) -> CGRect { fileprivate func calculateSliceAspectRatio(_ image: Image, size: CGSize) -> CGRect {
let w = CGFloat(image.w) let w = CGFloat(image.w)
let h = CGFloat(image.h) let h = CGFloat(image.h)
var srcX = CGFloat(0) var srcX = CGFloat(0)
@ -135,6 +135,6 @@ class ImageRenderer: NodeRenderer {
srcX = -(totalW - w) srcX = -(totalW - w)
} }
} }
return CGRectMake(srcX, srcY, totalW, totalH) return CGRect(x: srcX, y: srcY, width: totalW, height: totalH)
} }
} }

View File

@ -6,9 +6,9 @@ class NodeRenderer {
let ctx: RenderContext let ctx: RenderContext
private let onNodeChange: (Any) -> Void fileprivate let onNodeChange: (Any) -> Void
private let disposables = GroupDisposable() fileprivate let disposables = GroupDisposable()
private var active = false fileprivate var active = false
let animationCache: AnimationCache let animationCache: AnimationCache
init(node: Node, ctx: RenderContext, animationCache: AnimationCache) { init(node: Node, ctx: RenderContext, animationCache: AnimationCache) {
@ -26,27 +26,27 @@ class NodeRenderer {
observe(node().effectVar) observe(node().effectVar)
} }
func observe<E>(variable: Variable<E>) { func observe<E>(_ variable: Variable<E>) {
observe(variable.asObservable()) observe(variable.asObservable())
} }
func observe<E>(observable: Observable<E>) { func observe<E>(_ observable: Observable<E>) {
addDisposable(observable.subscribeNext(onNodeChange)) addDisposable(observable.subscribeNext(onNodeChange))
} }
func addDisposable(disposable: Disposable) { func addDisposable(_ disposable: Disposable) {
disposable.addTo(disposables) disposable.addTo(disposables)
} }
public func dispose() { open func dispose() {
removeObservers() removeObservers()
} }
public func node() -> Node { open func node() -> Node {
fatalError("Unsupported") fatalError("Unsupported")
} }
final public func render(force: Bool, opacity: Double) { final public func render(_ force: Bool, opacity: Double) {
if animationCache.isAnimating(node()) { if animationCache.isAnimating(node()) {
self.removeObservers() self.removeObservers()
if (!force) { if (!force) {
@ -58,26 +58,26 @@ class NodeRenderer {
doRender(force, opacity: opacity) doRender(force, opacity: opacity)
} }
func doRender(force: Bool, opacity: Double) { func doRender(_ force: Bool, opacity: Double) {
fatalError("Unsupported") fatalError("Unsupported")
} }
public func detectTouches(location: CGPoint) -> [Shape] { open func detectTouches(_ location: CGPoint) -> [Shape] {
return [] return []
} }
private func addObservers() { fileprivate func addObservers() {
if (!active) { if (!active) {
active = true active = true
doAddObservers() doAddObservers()
} }
} }
private func removeObservers() { fileprivate func removeObservers() {
if (active) { if (active) {
active = false active = false
disposables.dispose() disposables.dispose()
} }
} }
} }

View File

@ -2,44 +2,44 @@ import Foundation
import UIKit import UIKit
class RenderUtils { class RenderUtils {
class func mapColor(color: Color) -> CGColor { class func mapColor(_ color: Color) -> CGColor {
let red = CGFloat(Double(color.r()) / 255.0) let red = CGFloat(Double(color.r()) / 255.0)
let green = CGFloat(Double(color.g()) / 255.0) let green = CGFloat(Double(color.g()) / 255.0)
let blue = CGFloat(Double(color.b()) / 255.0) let blue = CGFloat(Double(color.b()) / 255.0)
let alpha = CGFloat(Double(color.a()) / 255.0) let alpha = CGFloat(Double(color.a()) / 255.0)
return UIColor(red: red, green: green, blue: blue, alpha: alpha).CGColor return UIColor(red: red, green: green, blue: blue, alpha: alpha).cgColor
} }
class func mapTransform(t: Transform) -> CGAffineTransform { class func mapTransform(_ t: Transform) -> CGAffineTransform {
return CGAffineTransform(a: CGFloat(t.m11), b: CGFloat(t.m12), c: CGFloat(t.m21), return CGAffineTransform(a: CGFloat(t.m11), b: CGFloat(t.m12), c: CGFloat(t.m21),
d: CGFloat(t.m22), tx: CGFloat(t.dx), ty: CGFloat(t.dy)) d: CGFloat(t.m22), tx: CGFloat(t.dx), ty: CGFloat(t.dy))
} }
class func mapLineJoin(join: LineJoin?) -> CGLineJoin { class func mapLineJoin(_ join: LineJoin?) -> CGLineJoin {
switch join { switch join {
case LineJoin.round?: return CGLineJoin.Round case LineJoin.round?: return CGLineJoin.round
case LineJoin.bevel?: return CGLineJoin.Bevel case LineJoin.bevel?: return CGLineJoin.bevel
default: return CGLineJoin.Miter default: return CGLineJoin.miter
} }
} }
class func mapLineCap(cap: LineCap?) -> CGLineCap { class func mapLineCap(_ cap: LineCap?) -> CGLineCap {
switch cap { switch cap {
case LineCap.round?: return CGLineCap.Round case LineCap.round?: return CGLineCap.round
case LineCap.square?: return CGLineCap.Square case LineCap.square?: return CGLineCap.square
default: return CGLineCap.Butt default: return CGLineCap.butt
} }
} }
class func mapDash(dashes: [Double]) -> UnsafeMutablePointer<CGFloat> { class func mapDash(_ dashes: [Double]) -> UnsafeMutablePointer<CGFloat> {
let p = UnsafeMutablePointer<CGFloat>(calloc(dashes.count, sizeof(CGFloat))) let p = UnsafeMutablePointer<CGFloat>(calloc(dashes.count, sizeof(CGFloat)))
for (index, item) in dashes.enumerate() { for (index, item) in dashes.enumerated() {
p[index] = CGFloat(item) p[index] = CGFloat(item)
} }
return p return p
} }
class func createNodeRenderer(node: Node, context: RenderContext, animationCache: AnimationCache) -> NodeRenderer { class func createNodeRenderer(_ node: Node, context: RenderContext, animationCache: AnimationCache) -> NodeRenderer {
if let group = node as? Group { if let group = node as? Group {
return GroupRenderer(group: group, ctx: context, animationCache: animationCache) return GroupRenderer(group: group, ctx: context, animationCache: animationCache)
} else if let shape = node as? Shape { } else if let shape = node as? Shape {
@ -52,7 +52,7 @@ class RenderUtils {
fatalError("Unsupported node: \(node)"); fatalError("Unsupported node: \(node)");
} }
class func applyOpacity(color: Color, opacity: Double) -> Color { class func applyOpacity(_ color: Color, opacity: Double) -> Color {
return Color.rgba(r: color.r(), g: color.g(), b: color.b(), a: Double(color.a()) / 255.0 * opacity) return Color.rgba(r: color.r(), g: color.g(), b: color.b(), a: Double(color.a()) / 255.0 * opacity)
} }
} }

View File

@ -21,61 +21,61 @@ class ShapeRenderer: NodeRenderer {
observe(shape.strokeVar) observe(shape.strokeVar)
} }
override func doRender(force: Bool, opacity: Double) { override func doRender(_ force: Bool, opacity: Double) {
setGeometry(shape.form, ctx: ctx.cgContext!) setGeometry(shape.form, ctx: ctx.cgContext!)
drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity) drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity)
} }
override func detectTouches(location: CGPoint) -> [Shape] { override func detectTouches(_ location: CGPoint) -> [Shape] {
var touchedShapes = [Shape]() var touchedShapes = [Shape]()
setGeometry(shape.form, ctx: ctx.cgContext!) setGeometry(shape.form, ctx: ctx.cgContext!)
var drawingMode: CGPathDrawingMode? = nil var drawingMode: CGPathDrawingMode? = nil
if let _ = shape.stroke, _ = shape.fill { if let _ = shape.stroke, let _ = shape.fill {
drawingMode = .FillStroke drawingMode = .fillStroke
} else if let _ = shape.stroke { } else if let _ = shape.stroke {
drawingMode = .Stroke drawingMode = .stroke
} else if let _ = shape.fill { } else if let _ = shape.fill {
drawingMode = .Fill drawingMode = .fill
} }
var contains = false var contains = false
if let mode = drawingMode { if let mode = drawingMode {
contains = CGContextPathContainsPoint(ctx.cgContext!, location, mode) contains = ctx.cgContext!.pathContains(location, mode: mode)
} }
if contains { if contains {
touchedShapes.append(shape) touchedShapes.append(shape)
} }
// Prepare for next figure hittesting - clear current context path // Prepare for next figure hittesting - clear current context path
CGContextBeginPath(ctx.cgContext!) ctx.cgContext!.beginPath()
return touchedShapes return touchedShapes
} }
private func setGeometry(locus: Locus, ctx: CGContext) { fileprivate func setGeometry(_ locus: Locus, ctx: CGContext) {
if let rect = locus as? Rect { if let rect = locus as? Rect {
CGContextAddRect(ctx, newCGRect(rect)) ctx.addRect(newCGRect(rect))
} else if let round = locus as? RoundRect { } else if let round = locus as? RoundRect {
let corners = CGSizeMake(CGFloat(round.rx), CGFloat(round.ry)) let corners = CGSize(width: CGFloat(round.rx), height: CGFloat(round.ry))
let path = UIBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners: let path = UIBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners:
UIRectCorner.AllCorners, cornerRadii: corners).CGPath UIRectCorner.allCorners, cornerRadii: corners).cgPath
CGContextAddPath(ctx, path) ctx.addPath(path)
} else if let circle = locus as? Circle { } else if let circle = locus as? Circle {
let cx = circle.cx let cx = circle.cx
let cy = circle.cy let cy = circle.cy
let r = circle.r let r = circle.r
CGContextAddEllipseInRect(ctx, CGRect(x: cx - r, y: cy - r, width: r * 2, height: r * 2)) ctx.addEllipse(in: CGRect(x: cx - r, y: cy - r, width: r * 2, height: r * 2))
} else if let ellipse = locus as? Ellipse { } else if let ellipse = locus as? Ellipse {
let cx = ellipse.cx let cx = ellipse.cx
let cy = ellipse.cy let cy = ellipse.cy
let rx = ellipse.rx let rx = ellipse.rx
let ry = ellipse.ry let ry = ellipse.ry
CGContextAddEllipseInRect(ctx, CGRect(x: cx - rx, y: cy - ry, width: rx * 2, height: ry * 2)) ctx.addEllipse(in: CGRect(x: cx - rx, y: cy - ry, width: rx * 2, height: ry * 2))
} else if let arc = locus as? Arc { } else if let arc = locus as? Arc {
if arc.ellipse.rx == arc.ellipse.ry { if arc.ellipse.rx == arc.ellipse.ry {
// Only circle arc supported for now // Only circle arc supported for now
CGContextAddPath(ctx, toBezierPath(arc).CGPath) ctx.addPath(toBezierPath(arc).cgPath)
} else { } else {
// http://stackoverflow.com/questions/11365775/how-to-draw-an-elliptical-arc-with-coregraphics // http://stackoverflow.com/questions/11365775/how-to-draw-an-elliptical-arc-with-coregraphics
// input parameters // input parameters
@ -85,60 +85,60 @@ class ShapeRenderer: NodeRenderer {
let r = CGFloat(ellipse.rx) let r = CGFloat(ellipse.rx)
let scale = CGFloat(ellipse.ry / ellipse.rx) let scale = CGFloat(ellipse.ry / ellipse.rx)
let path = CGPathCreateMutable() let path = CGMutablePath()
var t = CGAffineTransformMakeTranslation(CGFloat(ellipse.cx), CGFloat(ellipse.cy)) var t = CGAffineTransform(translationX: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
t = CGAffineTransformConcat(CGAffineTransformMakeScale(1.0, scale), t); t = CGAffineTransform(scaleX: 1.0, y: scale).concatenating(t);
CGPathAddArc(path, &t, 0, 0, r, startAngle, endAngle, false) CGPathAddArc(path, &t, 0, 0, r, startAngle, endAngle, false)
CGContextAddPath(ctx, path) ctx.addPath(path)
} }
} else if let point = locus as? Point { } else if let point = locus as? Point {
let path = UIBezierPath() let path = UIBezierPath()
path.moveToPoint(CGPointMake(CGFloat(point.x), CGFloat(point.y))) path.move(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
path.addLineToPoint(CGPointMake(CGFloat(point.x), CGFloat(point.y))) path.addLine(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
CGContextAddPath(ctx, path.CGPath) ctx.addPath(path.cgPath)
} else if let line = locus as? Line { } else if let line = locus as? Line {
let path = UIBezierPath() let path = UIBezierPath()
path.moveToPoint(CGPointMake(CGFloat(line.x1), CGFloat(line.y1))) path.move(to: CGPoint(x: CGFloat(line.x1), y: CGFloat(line.y1)))
path.addLineToPoint(CGPointMake(CGFloat(line.x2), CGFloat(line.y2))) path.addLine(to: CGPoint(x: CGFloat(line.x2), y: CGFloat(line.y2)))
CGContextAddPath(ctx, path.CGPath) ctx.addPath(path.cgPath)
} else if let polygon = locus as? Polygon { } else if let polygon = locus as? Polygon {
let path = toBezierPath(polygon.points) let path = toBezierPath(polygon.points)
path.closePath() path.close()
CGContextAddPath(ctx, path.CGPath) ctx.addPath(path.cgPath)
} else if let polygon = locus as? Polyline { } else if let polygon = locus as? Polyline {
CGContextAddPath(ctx, toBezierPath(polygon.points).CGPath) ctx.addPath(toBezierPath(polygon.points).cgPath)
} else if let path = locus as? Path { } else if let path = locus as? Path {
CGContextAddPath(ctx, toBezierPath(path).CGPath) ctx.addPath(toBezierPath(path).cgPath)
} else { } else {
print("Unsupported locus: \(locus)") print("Unsupported locus: \(locus)")
} }
} }
private func toBezierPath(arc: Arc) -> UIBezierPath { fileprivate func toBezierPath(_ arc: Arc) -> UIBezierPath {
let shift = CGFloat(arc.shift) let shift = CGFloat(arc.shift)
let end = shift + CGFloat(arc.extent) let end = shift + CGFloat(arc.extent)
let ellipse = arc.ellipse let ellipse = arc.ellipse
let center = CGPointMake(CGFloat(ellipse.cx), CGFloat(ellipse.cy)) 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 UIBezierPath(arcCenter: center, radius: CGFloat(ellipse.rx), startAngle: shift, endAngle: end, clockwise: true)
} }
private func toBezierPath(points: [Double]) -> UIBezierPath { fileprivate func toBezierPath(_ points: [Double]) -> UIBezierPath {
let parts = 0.stride(to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) } let parts = stride(from: 0, to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) }
let path = UIBezierPath() let path = UIBezierPath()
var first = true var first = true
for part in parts { for part in parts {
let point = CGPointMake(CGFloat(part[0]), CGFloat(part[1])) let point = CGPoint(x: CGFloat(part[0]), y: CGFloat(part[1]))
if (first) { if (first) {
path.moveToPoint(point) path.move(to: point)
first = false first = false
} else { } else {
path.addLineToPoint(point) path.addLine(to: point)
} }
} }
return path return path
} }
private func toBezierPath(path: Path) -> UIBezierPath { fileprivate func toBezierPath(_ path: Path) -> UIBezierPath {
let bezierPath = UIBezierPath() let bezierPath = UIBezierPath()
var currentPoint: CGPoint? var currentPoint: CGPoint?
@ -146,119 +146,119 @@ class ShapeRenderer: NodeRenderer {
var quadrPoint: CGPoint? var quadrPoint: CGPoint?
var initialPoint: CGPoint? var initialPoint: CGPoint?
func M(x: Double, y: Double) { func M(_ x: Double, y: Double) {
let point = CGPointMake(CGFloat(x), CGFloat(y)) let point = CGPoint(x: CGFloat(x), y: CGFloat(y))
bezierPath.moveToPoint(point) bezierPath.move(to: point)
setInitPoint(point) setInitPoint(point)
} }
func m(x: Double, y: Double) { func m(_ x: Double, y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
let next = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y) let next = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
bezierPath.moveToPoint(next) bezierPath.move(to: next)
setInitPoint(next) setInitPoint(next)
} else { } else {
M(x, y: y) M(x, y: y)
} }
} }
func L(x: Double, y: Double) { func L(_ x: Double, y: Double) {
lineTo(CGPointMake(CGFloat(x), CGFloat(y))) lineTo(CGPoint(x: CGFloat(x), y: CGFloat(y)))
} }
func l(x: Double, y: Double) { func l(_ x: Double, y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
lineTo(CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y)) lineTo(CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y))
} else { } else {
L(x, y: y) L(x, y: y)
} }
} }
func H(x: Double) { func H(_ x: Double) {
if let cur = currentPoint { if let cur = currentPoint {
lineTo(CGPointMake(CGFloat(x), CGFloat(cur.y))) lineTo(CGPoint(x: CGFloat(x), y: CGFloat(cur.y)))
} }
} }
func h(x: Double) { func h(_ x: Double) {
if let cur = currentPoint { if let cur = currentPoint {
lineTo(CGPointMake(CGFloat(x) + cur.x, CGFloat(cur.y))) lineTo(CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(cur.y)))
} }
} }
func V(y: Double) { func V(_ y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
lineTo(CGPointMake(CGFloat(cur.x), CGFloat(y))) lineTo(CGPoint(x: CGFloat(cur.x), y: CGFloat(y)))
} }
} }
func v(y: Double) { func v(_ y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
lineTo(CGPointMake(CGFloat(cur.x), CGFloat(y) + cur.y)) lineTo(CGPoint(x: CGFloat(cur.x), y: CGFloat(y) + cur.y))
} }
} }
func lineTo(p: CGPoint) { func lineTo(_ p: CGPoint) {
bezierPath.addLineToPoint(p) bezierPath.addLine(to: p)
setPoint(p) setPoint(p)
} }
func c(x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) { func c(_ x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
let endPoint = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y) let endPoint = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
let controlPoint1 = CGPointMake(CGFloat(x1) + cur.x, CGFloat(y1) + cur.y) let controlPoint1 = CGPoint(x: CGFloat(x1) + cur.x, y: CGFloat(y1) + cur.y)
let controlPoint2 = CGPointMake(CGFloat(x2) + cur.x, CGFloat(y2) + cur.y) let controlPoint2 = CGPoint(x: CGFloat(x2) + cur.x, y: CGFloat(y2) + cur.y)
bezierPath.addCurveToPoint(endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2) bezierPath.addCurve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
setCubicPoint(endPoint, cubic: controlPoint2) setCubicPoint(endPoint, cubic: controlPoint2)
} }
} }
func C(x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) { func C(_ x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
let endPoint = CGPointMake(CGFloat(x), CGFloat(y)) let endPoint = CGPoint(x: CGFloat(x), y: CGFloat(y))
let controlPoint1 = CGPointMake(CGFloat(x1), CGFloat(y1)) let controlPoint1 = CGPoint(x: CGFloat(x1), y: CGFloat(y1))
let controlPoint2 = CGPointMake(CGFloat(x2), CGFloat(y2)) let controlPoint2 = CGPoint(x: CGFloat(x2), y: CGFloat(y2))
bezierPath.addCurveToPoint(endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2) bezierPath.addCurve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
setCubicPoint(endPoint, cubic: controlPoint2) setCubicPoint(endPoint, cubic: controlPoint2)
} }
func s(x2: Double, y2: Double, x: Double, y: Double) { func s(_ x2: Double, y2: Double, x: Double, y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
let nextCubic = CGPointMake(CGFloat(x2) + cur.x, CGFloat(y2) + cur.y) let nextCubic = CGPoint(x: CGFloat(x2) + cur.x, y: CGFloat(y2) + cur.y)
let next = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y) let next = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
var xy1: CGPoint? var xy1: CGPoint?
if let curCubicVal = cubicPoint { if let curCubicVal = cubicPoint {
xy1 = CGPointMake(CGFloat(2 * cur.x) - curCubicVal.x, CGFloat(2 * cur.y) - curCubicVal.y) xy1 = CGPoint(x: CGFloat(2 * cur.x) - curCubicVal.x, y: CGFloat(2 * cur.y) - curCubicVal.y)
} else { } else {
xy1 = cur xy1 = cur
} }
bezierPath.addCurveToPoint(next, controlPoint1: xy1!, controlPoint2: nextCubic) bezierPath.addCurve(to: next, controlPoint1: xy1!, controlPoint2: nextCubic)
setCubicPoint(next, cubic: nextCubic) setCubicPoint(next, cubic: nextCubic)
} }
} }
func S(x2: Double, y2: Double, x: Double, y: Double) { func S(_ x2: Double, y2: Double, x: Double, y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
let nextCubic = CGPointMake(CGFloat(x2), CGFloat(y2)) let nextCubic = CGPoint(x: CGFloat(x2), y: CGFloat(y2))
let next = CGPointMake(CGFloat(x), CGFloat(y)) let next = CGPoint(x: CGFloat(x), y: CGFloat(y))
var xy1: CGPoint? var xy1: CGPoint?
if let curCubicVal = cubicPoint { if let curCubicVal = cubicPoint {
xy1 = CGPointMake(CGFloat(2 * cur.x) - curCubicVal.x, CGFloat(2 * cur.y) - curCubicVal.y) xy1 = CGPoint(x: CGFloat(2 * cur.x) - curCubicVal.x, y: CGFloat(2 * cur.y) - curCubicVal.y)
} else { } else {
xy1 = cur xy1 = cur
} }
bezierPath.addCurveToPoint(next, controlPoint1: xy1!, controlPoint2: nextCubic) bezierPath.addCurve(to: next, controlPoint1: xy1!, controlPoint2: nextCubic)
setCubicPoint(next, cubic: nextCubic) setCubicPoint(next, cubic: nextCubic)
} }
} }
func a(rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) { func a(_ rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
A(rx, ry: ry, angle: angle, largeArc: largeArc, sweep: sweep, x: x + Double(cur.x), y: y + Double(cur.y)) A(rx, ry: ry, angle: angle, largeArc: largeArc, sweep: sweep, x: x + Double(cur.x), y: y + Double(cur.y))
} }
} }
func A(rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) { func A(_ rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) {
if let cur = currentPoint { if let cur = currentPoint {
let x1 = Double(cur.x) let x1 = Double(cur.x)
let y1 = Double(cur.y) let y1 = Double(cur.y)
@ -294,19 +294,19 @@ class ShapeRenderer: NodeRenderer {
} }
} }
E(cx - rx, y: cy - ry, w: 2 * rx, h: 2 * ry, startAngle: t1, arcAngle: delta); E(cx - rx, y: cy - ry, w: 2 * rx, h: 2 * ry, startAngle: t1, arcAngle: delta);
setPoint(CGPointMake(CGFloat(x), CGFloat(y))) setPoint(CGPoint(x: CGFloat(x), y: CGFloat(y)))
} }
} }
func E(x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) { func E(_ x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) {
// TODO: only circle now // TODO: only circle now
let extent = CGFloat(startAngle) let extent = CGFloat(startAngle)
let end = extent + CGFloat(arcAngle) let end = extent + CGFloat(arcAngle)
let center = CGPointMake(CGFloat(x + w / 2), CGFloat(y + h / 2)) let center = CGPoint(x: CGFloat(x + w / 2), y: CGFloat(y + h / 2))
bezierPath.addArcWithCenter(center, radius: CGFloat(w / 2), startAngle: extent, endAngle: end, clockwise: true) bezierPath.addArc(withCenter: center, radius: CGFloat(w / 2), startAngle: extent, endAngle: end, clockwise: true)
} }
func e(x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) { func e(_ x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) {
// TODO: only circle now // TODO: only circle now
if let cur = currentPoint { if let cur = currentPoint {
E(x + Double(cur.x), y: y + Double(cur.y), w: w, h: h, startAngle: startAngle, arcAngle: arcAngle) E(x + Double(cur.x), y: y + Double(cur.y), w: w, h: h, startAngle: startAngle, arcAngle: arcAngle)
@ -317,21 +317,21 @@ class ShapeRenderer: NodeRenderer {
if let initPoint = initialPoint { if let initPoint = initialPoint {
lineTo(initPoint) lineTo(initPoint)
} }
bezierPath.closePath() bezierPath.close()
} }
func setCubicPoint(p: CGPoint, cubic: CGPoint) { func setCubicPoint(_ p: CGPoint, cubic: CGPoint) {
currentPoint = p currentPoint = p
cubicPoint = cubic cubicPoint = cubic
quadrPoint = nil quadrPoint = nil
} }
func setInitPoint(p: CGPoint) { func setInitPoint(_ p: CGPoint) {
setPoint(p) setPoint(p)
initialPoint = p initialPoint = p
} }
func setPoint(p: CGPoint) { func setPoint(_ p: CGPoint) {
currentPoint = p currentPoint = p
cubicPoint = nil cubicPoint = nil
quadrPoint = nil quadrPoint = nil
@ -343,27 +343,27 @@ class ShapeRenderer: NodeRenderer {
switch part.type { switch part.type {
case .M: case .M:
M(data[0], y: data[1]) M(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2)) data.removeSubrange((0 ..< 2))
while data.count >= 2 { while data.count >= 2 {
L(data[0], y: data[1]) L(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2)) data.removeSubrange((0 ..< 2))
} }
case .m: case .m:
m(data[0], y: data[1]) m(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2)) data.removeSubrange((0 ..< 2))
while data.count >= 2 { while data.count >= 2 {
l(data[0], y: data[1]) l(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2)) data.removeSubrange((0 ..< 2))
} }
case .L: case .L:
while data.count >= 2 { while data.count >= 2 {
L(data[0], y: data[1]) L(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2)) data.removeSubrange((0 ..< 2))
} }
case .l: case .l:
while data.count >= 2 { while data.count >= 2 {
l(data[0], y: data[1]) l(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2)) data.removeSubrange((0 ..< 2))
} }
case .H: case .H:
H(data[0]) H(data[0])
@ -376,22 +376,22 @@ class ShapeRenderer: NodeRenderer {
case .C: case .C:
while data.count >= 6 { while data.count >= 6 {
C(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5]) C(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5])
data.removeRange(Range(start: 0, end: 6)) data.removeSubrange((0 ..< 6))
} }
case .c: case .c:
while data.count >= 6 { while data.count >= 6 {
c(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5]) c(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5])
data.removeRange(Range(start: 0, end: 6)) data.removeSubrange((0 ..< 6))
} }
case .S: case .S:
while data.count >= 4 { while data.count >= 4 {
S(data[0], y2: data[1], x: data[2], y: data[3]) S(data[0], y2: data[1], x: data[2], y: data[3])
data.removeRange(Range(start: 0, end: 4)) data.removeSubrange((0 ..< 4))
} }
case .s: case .s:
while data.count >= 4 { while data.count >= 4 {
s(data[0], y2: data[1], x: data[2], y: data[3]) s(data[0], y2: data[1], x: data[2], y: data[3])
data.removeRange(Range(start: 0, end: 4)) data.removeSubrange((0 ..< 4))
} }
case .A: case .A:
let flags = numToBools(data[3]) let flags = numToBools(data[3])
@ -399,7 +399,7 @@ class ShapeRenderer: NodeRenderer {
case .a: case .a:
let flags = numToBools(data[3]) let flags = numToBools(data[3])
a(data[0], ry: data[1], angle: data[2], largeArc: flags[0], sweep: flags[1], x: data[4], y: data[5]) a(data[0], ry: data[1], angle: data[2], largeArc: flags[0], sweep: flags[1], x: data[4], y: data[5])
case .Z: case .z:
Z() Z()
default: default:
fatalError("Unknown segment: \(part.type)") fatalError("Unknown segment: \(part.type)")
@ -408,54 +408,54 @@ class ShapeRenderer: NodeRenderer {
return bezierPath return bezierPath
} }
private func numToBools(num: Double) -> [Bool] { fileprivate func numToBools(_ num: Double) -> [Bool] {
let val: Int = Int(num); let val: Int = Int(num);
return [(val & 1) > 0, (val & 2) > 0]; return [(val & 1) > 0, (val & 2) > 0];
} }
private func newCGRect(rect: Rect) -> CGRect { fileprivate func newCGRect(_ rect: Rect) -> CGRect {
return CGRect(x: CGFloat(rect.x), y: CGFloat(rect.y), width: CGFloat(rect.w), height: CGFloat(rect.h)) return CGRect(x: CGFloat(rect.x), y: CGFloat(rect.y), width: CGFloat(rect.w), height: CGFloat(rect.h))
} }
private func drawPath(fill: Fill?, stroke: Stroke?, ctx: CGContext?, opacity: Double) { fileprivate func drawPath(_ fill: Fill?, stroke: Stroke?, ctx: CGContext?, opacity: Double) {
var shouldStrokePath = false var shouldStrokePath = false
if fill is Gradient || stroke?.fill is Gradient { if fill is Gradient || stroke?.fill is Gradient {
shouldStrokePath = true shouldStrokePath = true
} }
if let fill = fill, stroke = stroke { if let fill = fill, let stroke = stroke {
let path = CGContextCopyPath(ctx!) let path = ctx!.path
setFill(fill, ctx: ctx, opacity: opacity) setFill(fill, ctx: ctx, opacity: opacity)
if stroke.fill is Gradient && !(fill is Gradient) { if stroke.fill is Gradient && !(fill is Gradient) {
CGContextDrawPath(ctx!, .Fill) ctx!.drawPath(using: .fill)
} }
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, path: path, mode: .FillStroke) drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, path: path, mode: .fillStroke)
return return
} }
if let fill = fill { if let fill = fill {
setFill(fill, ctx: ctx, opacity: opacity) setFill(fill, ctx: ctx, opacity: opacity)
CGContextDrawPath(ctx!, .Fill) ctx!.drawPath(using: .fill)
return return
} }
if let stroke = stroke { if let stroke = stroke {
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, mode: .Stroke) drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, mode: .stroke)
return return
} }
CGContextSetLineWidth(ctx!, 2.0) ctx!.setLineWidth(2.0)
CGContextSetStrokeColorWithColor(ctx!, UIColor.blackColor().CGColor) ctx!.setStrokeColor(UIColor.black.cgColor)
CGContextDrawPath(ctx!, .Stroke) ctx!.drawPath(using: .stroke)
} }
private func setFill(fill: Fill?, ctx: CGContext?, opacity: Double) { fileprivate func setFill(_ fill: Fill?, ctx: CGContext?, opacity: Double) {
guard let fill = fill else { guard let fill = fill else {
return return
} }
if let fillColor = fill as? Color { if let fillColor = fill as? Color {
let color = RenderUtils.applyOpacity(fillColor, opacity: opacity) let color = RenderUtils.applyOpacity(fillColor, opacity: opacity)
CGContextSetFillColorWithColor(ctx!, RenderUtils.mapColor(color)) ctx!.setFillColor(RenderUtils.mapColor(color))
} else if let gradient = fill as? Gradient { } else if let gradient = fill as? Gradient {
drawGradient(gradient, ctx: ctx, opacity: opacity) drawGradient(gradient, ctx: ctx, opacity: opacity)
} else { } else {
@ -463,9 +463,9 @@ class ShapeRenderer: NodeRenderer {
} }
} }
private func drawWithStroke(stroke: Stroke, ctx: CGContext?, opacity: Double, shouldStrokePath: Bool = false, path: CGPath? = nil, mode: CGPathDrawingMode) { fileprivate func drawWithStroke(_ stroke: Stroke, ctx: CGContext?, opacity: Double, shouldStrokePath: Bool = false, path: CGPath? = nil, mode: CGPathDrawingMode) {
if let path = path where shouldStrokePath { if let path = path , shouldStrokePath {
CGContextAddPath(ctx!, path) ctx!.addPath(path)
} }
setStrokeAttributes(stroke, ctx: ctx) setStrokeAttributes(stroke, ctx: ctx)
@ -476,42 +476,42 @@ class ShapeRenderer: NodeRenderer {
colorStroke(stroke, ctx: ctx, opacity: opacity) colorStroke(stroke, ctx: ctx, opacity: opacity)
} }
if shouldStrokePath { if shouldStrokePath {
CGContextStrokePath(ctx!) ctx!.strokePath()
} else { } else {
CGContextDrawPath(ctx!, mode) ctx!.drawPath(using: mode)
} }
} }
private func setStrokeAttributes(stroke: Stroke, ctx: CGContext?) { fileprivate func setStrokeAttributes(_ stroke: Stroke, ctx: CGContext?) {
CGContextSetLineWidth(ctx!, CGFloat(stroke.width)) ctx!.setLineWidth(CGFloat(stroke.width))
CGContextSetLineJoin(ctx!, RenderUtils.mapLineJoin(stroke.join)) ctx!.setLineJoin(RenderUtils.mapLineJoin(stroke.join))
CGContextSetLineCap(ctx!, RenderUtils.mapLineCap(stroke.cap)) ctx!.setLineCap(RenderUtils.mapLineCap(stroke.cap))
let dashes = stroke.dashes let dashes = stroke.dashes
if !dashes.isEmpty { if !dashes.isEmpty {
let dashPointer = RenderUtils.mapDash(dashes) let dashPointer = RenderUtils.mapDash(dashes)
CGContextSetLineDash(ctx!, 0, dashPointer, dashes.count) CGContextSetLineDash(ctx!, 0, dashPointer, dashes.count)
dashPointer.dealloc(dashes.count) dashPointer.deallocateCapacity(dashes.count)
} }
} }
private func colorStroke(stroke: Stroke, ctx: CGContext?, opacity: Double) { fileprivate func colorStroke(_ stroke: Stroke, ctx: CGContext?, opacity: Double) {
guard let strokeColor = stroke.fill as? Color else { guard let strokeColor = stroke.fill as? Color else {
return return
} }
let color = RenderUtils.applyOpacity(strokeColor, opacity: opacity) let color = RenderUtils.applyOpacity(strokeColor, opacity: opacity)
CGContextSetStrokeColorWithColor(ctx!, RenderUtils.mapColor(color)) ctx!.setStrokeColor(RenderUtils.mapColor(color))
} }
private func gradientStroke(stroke: Stroke, ctx: CGContext?, opacity: Double) { fileprivate func gradientStroke(_ stroke: Stroke, ctx: CGContext?, opacity: Double) {
guard let gradient = stroke.fill as? Gradient else { guard let gradient = stroke.fill as? Gradient else {
return return
} }
CGContextReplacePathWithStrokedPath(ctx!) ctx!.replacePathWithStrokedPath()
drawGradient(gradient, ctx: ctx, opacity: opacity) drawGradient(gradient, ctx: ctx, opacity: opacity)
} }
private func drawGradient(gradient: Gradient, ctx: CGContext?, opacity: Double) { fileprivate func drawGradient(_ gradient: Gradient, ctx: CGContext?, opacity: Double) {
CGContextSaveGState(ctx!) ctx!.saveGState()
var colors: [CGColor] = [] var colors: [CGColor] = []
var stops: [CGFloat] = [] var stops: [CGFloat] = []
for stop in gradient.stops { for stop in gradient.stops {
@ -521,22 +521,22 @@ class ShapeRenderer: NodeRenderer {
} }
if let gradient = gradient as? LinearGradient { if let gradient = gradient as? LinearGradient {
var start = CGPointMake(CGFloat(gradient.x1), CGFloat(gradient.y1)) var start = CGPoint(x: CGFloat(gradient.x1), y: CGFloat(gradient.y1))
var end = CGPointMake(CGFloat(gradient.x2), CGFloat(gradient.y2)) var end = CGPoint(x: CGFloat(gradient.x2), y: CGFloat(gradient.y2))
if !gradient.userSpace { if !gradient.userSpace {
let bounds = CGContextGetPathBoundingBox(ctx!) let bounds = ctx!.boundingBoxOfPath
start = CGPointMake(start.x * bounds.width + bounds.minX, start.y * bounds.height + bounds.minY) start = CGPoint(x: start.x * bounds.width + bounds.minX, y: start.y * bounds.height + bounds.minY)
end = CGPointMake(end.x * bounds.width + bounds.minX, end.y * bounds.height + bounds.minY) end = CGPoint(x: end.x * bounds.width + bounds.minX, y: end.y * bounds.height + bounds.minY)
} }
CGContextClip(ctx!) ctx!.clip()
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops) let cgGradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: stops)
CGContextDrawLinearGradient(ctx!, cgGradient!, start, end, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation]) ctx!.drawLinearGradient(cgGradient!, start: start, end: end, options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
} else if let gradient = gradient as? RadialGradient { } else if let gradient = gradient as? RadialGradient {
var innerCenter = CGPointMake(CGFloat(gradient.fx), CGFloat(gradient.fy)) var innerCenter = CGPoint(x: CGFloat(gradient.fx), y: CGFloat(gradient.fy))
var outerCenter = CGPointMake(CGFloat(gradient.cx), CGFloat(gradient.cy)) var outerCenter = CGPoint(x: CGFloat(gradient.cx), y: CGFloat(gradient.cy))
var radius = CGFloat(gradient.r) var radius = CGFloat(gradient.r)
if !gradient.userSpace { if !gradient.userSpace {
var bounds = CGContextGetPathBoundingBox(ctx!) var bounds = ctx!.boundingBoxOfPath
var scaleX: CGFloat = 1 var scaleX: CGFloat = 1
var scaleY: CGFloat = 1 var scaleY: CGFloat = 1
if bounds.width > bounds.height { if bounds.width > bounds.height {
@ -544,18 +544,18 @@ class ShapeRenderer: NodeRenderer {
} else { } else {
scaleX = bounds.width / bounds.height scaleX = bounds.width / bounds.height
} }
CGContextScaleCTM(ctx!, scaleX, scaleY) ctx!.scaleBy(x: scaleX, y: scaleY)
bounds = CGContextGetPathBoundingBox(ctx!) bounds = ctx!.boundingBoxOfPath
innerCenter = CGPointMake(innerCenter.x * bounds.width + bounds.minX, innerCenter.y * bounds.height + bounds.minY) innerCenter = CGPoint(x: innerCenter.x * bounds.width + bounds.minX, y: innerCenter.y * bounds.height + bounds.minY)
outerCenter = CGPointMake(outerCenter.x * bounds.width + bounds.minX, outerCenter.y * bounds.height + bounds.minY) outerCenter = CGPoint(x: outerCenter.x * bounds.width + bounds.minX, y: outerCenter.y * bounds.height + bounds.minY)
radius = min(radius * bounds.width, radius * bounds.height) radius = min(radius * bounds.width, radius * bounds.height)
} }
CGContextClip(ctx!) ctx!.clip()
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops) let cgGradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: stops)
CGContextDrawRadialGradient(ctx!, cgGradient!, innerCenter, 0, outerCenter, radius, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation]) ctx!.drawRadialGradient(cgGradient!, startCenter: innerCenter, startRadius: 0, endCenter: outerCenter, endRadius: radius, options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
} }
CGContextRestoreGState(ctx!) ctx!.restoreGState()
} }
} }

View File

@ -22,17 +22,17 @@ class TextRenderer: NodeRenderer {
observe(text.baselineVar) observe(text.baselineVar)
} }
override func doRender(force: Bool, opacity: Double) { override func doRender(_ force: Bool, opacity: Double) {
let message = text.text let message = text.text
var font: UIFont var font: UIFont
if let textFont = text.font { if let textFont = text.font {
if let customFont = UIFont(name: textFont.name, size: CGFloat(textFont.size)) { if let customFont = UIFont(name: textFont.name, size: CGFloat(textFont.size)) {
font = customFont font = customFont
} else { } else {
font = UIFont.systemFontOfSize(CGFloat(textFont.size)) font = UIFont.systemFont(ofSize: CGFloat(textFont.size))
} }
} else { } else {
font = UIFont.systemFontOfSize(UIFont.systemFontSize()) font = UIFont.systemFont(ofSize: UIFont.systemFontSize)
} }
// positive NSBaselineOffsetAttributeName values don't work, couldn't find why // positive NSBaselineOffsetAttributeName values don't work, couldn't find why
// for now move the rect itself // for now move the rect itself
@ -41,25 +41,25 @@ class TextRenderer: NodeRenderer {
color = RenderUtils.applyOpacity(color, opacity: opacity) color = RenderUtils.applyOpacity(color, opacity: opacity)
let textAttributes = [ let textAttributes = [
NSFontAttributeName: font, NSFontAttributeName: font,
NSForegroundColorAttributeName: getTextColor(color)] NSForegroundColorAttributeName: getTextColor(color)] as [String : Any]
let textSize = NSString(string: text.text).sizeWithAttributes(textAttributes) let textSize = NSString(string: text.text).size(attributes: textAttributes)
guard let cgContext = ctx.cgContext else { guard let cgContext = ctx.cgContext else {
return return
} }
UIGraphicsPushContext(cgContext) UIGraphicsPushContext(cgContext)
message.drawInRect(CGRectMake(calculateAlignmentOffset(text, font: font), calculateBaselineOffset(text, font: font), message.draw(in: CGRect(x: calculateAlignmentOffset(text, font: font), y: calculateBaselineOffset(text, font: font),
CGFloat(textSize.width), CGFloat(textSize.height)), withAttributes: textAttributes) width: CGFloat(textSize.width), height: CGFloat(textSize.height)), withAttributes: textAttributes)
UIGraphicsPopContext() UIGraphicsPopContext()
} }
} }
override func detectTouches(location: CGPoint) -> [Shape] { override func detectTouches(_ location: CGPoint) -> [Shape] {
return [] return []
} }
private func calculateBaselineOffset(text: Text, font: UIFont) -> CGFloat { fileprivate func calculateBaselineOffset(_ text: Text, font: UIFont) -> CGFloat {
var baselineOffset = CGFloat(0) var baselineOffset = CGFloat(0)
switch text.baseline { switch text.baseline {
case Baseline.alphabetic: case Baseline.alphabetic:
@ -74,11 +74,11 @@ class TextRenderer: NodeRenderer {
return -baselineOffset return -baselineOffset
} }
private func calculateAlignmentOffset(text: Text, font: UIFont) -> CGFloat { fileprivate func calculateAlignmentOffset(_ text: Text, font: UIFont) -> CGFloat {
let textAttributes = [ let textAttributes = [
NSFontAttributeName: font NSFontAttributeName: font
] ]
let textSize = NSString(string: text.text).sizeWithAttributes(textAttributes) let textSize = NSString(string: text.text).size(attributes: textAttributes)
var alignmentOffset = CGFloat(0) var alignmentOffset = CGFloat(0)
switch text.align { switch text.align {
case Align.mid: case Align.mid:
@ -91,10 +91,10 @@ class TextRenderer: NodeRenderer {
return -alignmentOffset return -alignmentOffset
} }
private func getTextColor(fill: Fill) -> UIColor { fileprivate func getTextColor(_ fill: Fill) -> UIColor {
if let color = fill as? Color { if let color = fill as? Color {
return UIColor(CGColor: RenderUtils.mapColor(color)) return UIColor(cgColor: RenderUtils.mapColor(color))
} }
return UIColor.blackColor() return UIColor.black
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -2,18 +2,18 @@ import Foundation
class SVGParserRegexHelper { class SVGParserRegexHelper {
private static let transformAttributePattern = "([a-z]+)\\(((\\-?\\d+\\.?\\d*\\s*,?\\s*)+)\\)" fileprivate static let transformAttributePattern = "([a-z]+)\\(((\\-?\\d+\\.?\\d*\\s*,?\\s*)+)\\)"
private static let transformPattern = "\\-?\\d+\\.?\\d*" fileprivate static let transformPattern = "\\-?\\d+\\.?\\d*"
private static let textElementPattern = "<text.*?>((?s:.*))<\\/text>" fileprivate static let textElementPattern = "<text.*?>((?s:.*))<\\/text>"
private static var transformMatcher: NSRegularExpression? fileprivate static var transformMatcher: NSRegularExpression?
private static var transformAttributeMatcher: NSRegularExpression? fileprivate static var transformAttributeMatcher: NSRegularExpression?
private static var textElementMatcher: NSRegularExpression? fileprivate static var textElementMatcher: NSRegularExpression?
class func getTransformAttributeMatcher() -> NSRegularExpression? { class func getTransformAttributeMatcher() -> NSRegularExpression? {
if self.transformAttributeMatcher == nil { if self.transformAttributeMatcher == nil {
do { do {
self.transformAttributeMatcher = try NSRegularExpression(pattern: transformAttributePattern, options: .CaseInsensitive) self.transformAttributeMatcher = try NSRegularExpression(pattern: transformAttributePattern, options: .caseInsensitive)
} catch { } catch {
} }
@ -24,7 +24,7 @@ class SVGParserRegexHelper {
class func getTransformMatcher() -> NSRegularExpression? { class func getTransformMatcher() -> NSRegularExpression? {
if self.transformMatcher == nil { if self.transformMatcher == nil {
do { do {
self.transformMatcher = try NSRegularExpression(pattern: transformPattern, options: .CaseInsensitive) self.transformMatcher = try NSRegularExpression(pattern: transformPattern, options: .caseInsensitive)
} catch { } catch {
} }
@ -35,7 +35,7 @@ class SVGParserRegexHelper {
class func getTextElementMatcher() -> NSRegularExpression? { class func getTextElementMatcher() -> NSRegularExpression? {
if self.textElementMatcher == nil { if self.textElementMatcher == nil {
do { do {
self.textElementMatcher = try NSRegularExpression(pattern: textElementPattern, options: .CaseInsensitive) self.textElementMatcher = try NSRegularExpression(pattern: textElementPattern, options: .caseInsensitive)
} catch { } catch {
} }

View File

@ -17,15 +17,15 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
var completion: ((Bool) -> Void)? var completion: ((Bool) -> Void)?
/// startTime: animation start date /// startTime: animation start date
private var startTime: NSDate! fileprivate var startTime: Date!
private var animationDuration: NSTimeInterval! fileprivate var animationDuration: TimeInterval!
private var animatingTimer: NSTimer! fileprivate var animatingTimer: Timer!
/// animating: A block (closure) object to be executed when the animation is animating. This block has no return value and takes a single CGFloat argument that indicates the progress of the animation (From 0 ..< 1) /// animating: A block (closure) object to be executed when the animation is animating. This block has no return value and takes a single CGFloat argument that indicates the progress of the animation (From 0 ..< 1)
var animating: ((CGFloat) -> Void)? { var animating: ((CGFloat) -> Void)? {
willSet { willSet {
if animatingTimer == nil { if animatingTimer == nil {
animatingTimer = NSTimer(timeInterval: 0, target: self, selector: "animationIsAnimating:", userInfo: nil, repeats: true) animatingTimer = Timer(timeInterval: 0, target: self, selector: #selector(CAAnimationDelegateImpl.animationIsAnimating(_:)), userInfo: nil, repeats: true)
} }
} }
} }
@ -35,12 +35,12 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
- parameter theAnimation: the animation about to start - parameter theAnimation: the animation about to start
*/ */
func animationDidStart(theAnimation: CAAnimation) { func animationDidStart(_ theAnimation: CAAnimation) {
start?() start?()
if animating != nil { if animating != nil {
animationDuration = theAnimation.duration animationDuration = theAnimation.duration
startTime = NSDate() startTime = Date()
NSRunLoop.currentRunLoop().addTimer(animatingTimer, forMode: NSDefaultRunLoopMode) RunLoop.current.add(animatingTimer, forMode: RunLoopMode.defaultRunLoopMode)
} }
} }
@ -50,7 +50,7 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
- parameter theAnimation: the animation about to end - parameter theAnimation: the animation about to end
- parameter finished: A Boolean value indicates whether or not the animations actually finished. - parameter finished: A Boolean value indicates whether or not the animations actually finished.
*/ */
func animationDidStop(theAnimation: CAAnimation, finished: Bool) { func animationDidStop(_ theAnimation: CAAnimation, finished: Bool) {
completion?(finished) completion?(finished)
animatingTimer?.invalidate() animatingTimer?.invalidate()
} }
@ -60,8 +60,8 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
- parameter timer: timer - parameter timer: timer
*/ */
func animationIsAnimating(timer: NSTimer) { func animationIsAnimating(_ timer: Timer) {
let progress = CGFloat(NSDate().timeIntervalSinceDate(startTime) / animationDuration) let progress = CGFloat(Date().timeIntervalSince(startTime) / animationDuration)
if progress <= 1.0 { if progress <= 1.0 {
animating?(progress) animating?(progress)
} }
@ -152,8 +152,8 @@ public extension CALayer {
- parameter key: A string that identifies the animation. Only one animation per unique key is added to the layer. The special key kCATransition is automatically used for transition animations. You may specify nil for this parameter. - parameter key: A string that identifies the animation. Only one animation per unique key is added to the layer. The special key kCATransition is automatically used for transition animations. You may specify nil for this parameter.
- parameter completion: A block object to be executed when the animation ends. This block has no return value and takes a single Boolean argument that indicates whether or not the animations actually finished before the completion handler was called. Default value is nil. - parameter completion: A block object to be executed when the animation ends. This block has no return value and takes a single Boolean argument that indicates whether or not the animations actually finished before the completion handler was called. Default value is nil.
*/ */
func addAnimation(anim: CAAnimation, forKey key: String?, withCompletion completion: ((Bool) -> Void)?) { func addAnimation(_ anim: CAAnimation, forKey key: String?, withCompletion completion: ((Bool) -> Void)?) {
anim.completion = completion anim.completion = completion
addAnimation(anim, forKey: key) add(anim, forKey: key)
} }
} }

View File

@ -1,7 +1,7 @@
import Foundation import Foundation
extension NSTimer { extension Timer {
/** /**
Creates and schedules a one-time `NSTimer` instance. Creates and schedules a one-time `NSTimer` instance.
@ -11,10 +11,10 @@ extension NSTimer {
- Returns: The newly-created `NSTimer` instance. - Returns: The newly-created `NSTimer` instance.
*/ */
class func schedule(delay delay: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer { class func schedule(delay: TimeInterval, handler: @escaping (Timer!) -> Void) -> Timer {
let fireDate = delay + CFAbsoluteTimeGetCurrent() let fireDate = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler) let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes) CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer return timer
} }
@ -29,10 +29,10 @@ extension NSTimer {
- Returns: The newly-created `NSTimer` instance. - Returns: The newly-created `NSTimer` instance.
*/ */
class func schedule(repeatInterval interval: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer { class func schedule(repeatInterval interval: TimeInterval, handler: @escaping (Timer!) -> Void) -> Timer {
let fireDate = interval + CFAbsoluteTimeGetCurrent() let fireDate = interval + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler) let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes) CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer return timer
} }
} }

View File

@ -5,10 +5,10 @@ import UIKit
/// MacawView is a main class used to embed Macaw scene into your Cocoa UI. /// MacawView is a main class used to embed Macaw scene into your Cocoa UI.
/// You could create your own view extended from MacawView with predefined scene. /// You could create your own view extended from MacawView with predefined scene.
/// ///
public class MacawView: UIView { open class MacawView: UIView {
/// Scene root node /// Scene root node
public var node: Node = Group() { open var node: Node = Group() {
willSet { willSet {
nodesMap.remove(node) nodesMap.remove(node)
} }
@ -26,7 +26,7 @@ public class MacawView: UIView {
} }
} }
override public var frame: CGRect { override open var frame: CGRect {
didSet { didSet {
super.frame = frame super.frame = frame
@ -40,7 +40,7 @@ public class MacawView: UIView {
} }
} }
override public func didMoveToSuperview() { override open func didMoveToSuperview() {
super.didMoveToSuperview() super.didMoveToSuperview()
if !frameSetFirstTime { if !frameSetFirstTime {
@ -51,7 +51,7 @@ public class MacawView: UIView {
animationProducer.addStoredAnimations(node) animationProducer.addStoredAnimations(node)
} }
private var selectedShape: Shape? = nil fileprivate var selectedShape: Shape? = nil
var context: RenderContext! var context: RenderContext!
var renderer: NodeRenderer? var renderer: NodeRenderer?
@ -86,26 +86,26 @@ public class MacawView: UIView {
self.init(node: Group(), coder: aDecoder) self.init(node: Group(), coder: aDecoder)
} }
override public func drawRect(rect: CGRect) { override open func draw(_ rect: CGRect) {
self.context.cgContext = UIGraphicsGetCurrentContext() self.context.cgContext = UIGraphicsGetCurrentContext()
CGContextSaveGState(self.context.cgContext!) self.context.cgContext!.saveGState()
CGContextConcatCTM(self.context.cgContext!, RenderUtils.mapTransform(node.place)) self.context.cgContext!.concatenate(RenderUtils.mapTransform(node.place))
renderer?.render(false, opacity: node.opacity) renderer?.render(false, opacity: node.opacity)
CGContextRestoreGState(self.context.cgContext!) self.context.cgContext!.restoreGState()
} }
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.selectedShape = nil self.selectedShape = nil
if let inverted = node.place.invert() { if let inverted = node.place.invert() {
for touch in touches { for touch in touches {
let location = touch.locationInView(self) let location = touch.location(in: self)
let translatedLocation = CGPointApplyAffineTransform(location, RenderUtils.mapTransform(inverted)) let translatedLocation = location.applying(RenderUtils.mapTransform(inverted))
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y) let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
CGContextSaveGState(self.context.cgContext!) self.context.cgContext!.saveGState()
CGContextConcatCTM(self.context.cgContext!, RenderUtils.mapTransform(node.place)) self.context.cgContext!.concatenate(RenderUtils.mapTransform(node.place))
let shapes = renderer?.detectTouches(offsetLocation) let shapes = renderer?.detectTouches(offsetLocation)
CGContextRestoreGState(self.context.cgContext!) self.context.cgContext!.restoreGState()
self.selectedShape = shapes?.first self.selectedShape = shapes?.first
if let shape = self.selectedShape { if let shape = self.selectedShape {
shape.onTap.onNext(TapEvent(location: Point(x: Double(offsetLocation.x), y: Double(offsetLocation.y)))) shape.onTap.onNext(TapEvent(location: Point(x: Double(offsetLocation.x), y: Double(offsetLocation.y))))
@ -115,20 +115,20 @@ public class MacawView: UIView {
} }
} }
func handlePan(recognizer: UIPanGestureRecognizer) { func handlePan(_ recognizer: UIPanGestureRecognizer) {
var translation = recognizer.translationInView(self) let translation = recognizer.translation(in: self)
recognizer.setTranslation(CGPointZero, inView: self) recognizer.setTranslation(CGPoint.zero, in: self)
if let shape = self.selectedShape { if let shape = self.selectedShape {
// get the rotation and scale of the shape and apply to the translation // get the rotation and scale of the shape and apply to the translation
let transform = shape.place let transform = shape.place
let rotation = -CGFloat(atan2f(Float(transform.m12), Float(transform.m11))) let rotation = -CGFloat(atan2f(Float(transform.m12), Float(transform.m11)))
let scale = CGFloat(sqrt(transform.m11 * transform.m11 + transform.m21 * transform.m21)) let scale = CGFloat(sqrt(transform.m11 * transform.m11 + transform.m21 * transform.m21))
var translatedLocation = CGPointApplyAffineTransform(translation, CGAffineTransformMakeRotation(rotation)) let translatedLocation = translation.applying(CGAffineTransform(rotationAngle: rotation))
shape.onPan.onNext(PanEvent(dx: Double(translatedLocation.x / scale), dy: Double(translatedLocation.y / scale))) shape.onPan.onNext(PanEvent(dx: Double(translatedLocation.x / scale), dy: Double(translatedLocation.y / scale)))
} }
} }
func handleRotation(recognizer: UIRotationGestureRecognizer) { func handleRotation(_ recognizer: UIRotationGestureRecognizer) {
let rotation = Double(recognizer.rotation) let rotation = Double(recognizer.rotation)
recognizer.rotation = 0 recognizer.rotation = 0
if let shape = self.selectedShape { if let shape = self.selectedShape {
@ -136,7 +136,7 @@ public class MacawView: UIView {
} }
} }
func handlePinch(recognizer: UIPinchGestureRecognizer) { func handlePinch(_ recognizer: UIPinchGestureRecognizer) {
let scale = Double(recognizer.scale) let scale = Double(recognizer.scale)
recognizer.scale = 1 recognizer.scale = 1
if let shape = self.selectedShape { if let shape = self.selectedShape {

View File

@ -8,7 +8,7 @@ class NodesMap {
var map = [Node: MacawView]() var map = [Node: MacawView]()
// MARK: - Macaw View // MARK: - Macaw View
func add(node: Node, view: MacawView) { func add(_ node: Node, view: MacawView) {
map[node] = view map[node] = view
if let group = node as? Group { if let group = node as? Group {
@ -19,17 +19,17 @@ class NodesMap {
} }
} }
func getView(node: Node) -> MacawView? { func getView(_ node: Node) -> MacawView? {
return map[node] return map[node]
} }
func remove(node: Node) { func remove(_ node: Node) {
map.removeValueForKey(node) map.removeValue(forKey: node)
parentsMap.removeValueForKey(node) parentsMap.removeValue(forKey: node)
} }
// MARK: - Parents // MARK: - Parents
func add(node: Node, parent: Node) { func add(_ node: Node, parent: Node) {
if var nodesSet = parentsMap[node] { if var nodesSet = parentsMap[node] {
nodesSet.insert(parent) nodesSet.insert(parent)
} else { } else {
@ -37,7 +37,7 @@ class NodesMap {
} }
} }
func parents(node: Node) -> [Node] { func parents(_ node: Node) -> [Node] {
guard let nodesSet = parentsMap[node] else { guard let nodesSet = parentsMap[node] else {
return [] return []
} }

View File

@ -5,7 +5,7 @@ class ShapeLayer: CAShapeLayer {
var renderTransform: CGAffineTransform? var renderTransform: CGAffineTransform?
var animationCache: AnimationCache? var animationCache: AnimationCache?
override func drawInContext(ctx: CGContext) { override func draw(in ctx: CGContext) {
guard let node = node else { guard let node = node else {
return return
} }
@ -14,15 +14,15 @@ class ShapeLayer: CAShapeLayer {
return return
} }
let renderContext = RenderContext(view: .None) let renderContext = RenderContext(view: .none)
renderContext.cgContext = ctx renderContext.cgContext = ctx
if let renderTransform = renderTransform { if let renderTransform = renderTransform {
CGContextConcatCTM(ctx, renderTransform) ctx.concatenate(renderTransform)
} }
let renderer = RenderUtils.createNodeRenderer(node, context: renderContext, animationCache: animationCache) let renderer = RenderUtils.createNodeRenderer(node, context: renderContext, animationCache: animationCache)
renderer.render(true, opacity: 1.0) renderer.render(true, opacity: 1.0)
renderer.dispose() renderer.dispose()
} }
} }