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

View File

@ -14,31 +14,31 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
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.
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.
// 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.
// 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.
}
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.
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:.
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@ class RectShapeView: MacawView {
var rectShape: Shape!
required init?(coder aDecoder: NSCoder) {
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenSize: CGRect = UIScreen.main.bounds
let rect = RoundRect(
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)
}
}
}

View File

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

View File

@ -135,17 +135,17 @@ class PathExampleView: MacawView {
}
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()
}
}
func updateScale(scale: Float) {
func updateScale(_ scale: Float) {
let rotation = GeomUtils.centerRotation(node: sceneGroup, place: initialTransform, angle: M_PI_4 * Double(scale))
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 t1 = Transform.identity
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)
}
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)
}

View File

@ -13,12 +13,12 @@ import Macaw
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.rotate(angle: M_PI_4, x: 150, y: 80),
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.rotate(angle: M_PI_4, x: 150, y: 80)",
"Transform.rotate(angle: M_PI_4)"]
@ -27,10 +27,10 @@ class TransformExampleView: MacawView {
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 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))
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))
}
private static func newAxes() -> Node {
fileprivate static func newAxes() -> Node {
var items: [Node] = []
let gray = Color(val: 0xF0F0F0)
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
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let count = viewControllers?.count else {
return 0
}
@ -22,22 +22,22 @@ class MenuViewController: UIViewController, UITableViewDataSource, UITableViewDe
return count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("menu_cell")!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
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
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
guard let selectedCtrl = viewControllers?[indexPath.row] else {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let selectedCtrl = viewControllers?[(indexPath as NSIndexPath).row] else {
return
}
pageViewController?.setViewControllers([selectedCtrl],
direction: .Forward, animated: true, completion: nil)
direction: .forward, animated: true, completion: nil)
}
}

View File

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

View File

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

View File

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

View File

@ -1,35 +1,35 @@
public class Animation {
open class Animation {
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
}
public func delay(delay: Double) -> Animation {
open func delay(_ delay: Double) -> Animation {
return self
}
public func cycle(count: Double) -> Animation {
open func cycle(_ count: Double) -> Animation {
return self
}
public func reverse() -> Animation {
open func reverse() -> Animation {
return self
}
public func autoreversed() -> Animation {
open func autoreversed() -> Animation {
return self
}
public func onComplete(_: (() -> ())) -> Animation {
open func onComplete(_: (() -> ())) -> Animation {
return self
}
}

View File

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

View File

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

View File

@ -2,14 +2,14 @@
import Foundation
class AnimationUtils {
class func absolutePosition(node: Node) -> Transform {
class func absolutePosition(_ node: Node) -> Transform {
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 parent = nodesMap.parents(node).first
while parent != .None {
while parent != .none {
transform = GeomUtils.concat(t1: parent!.place, t2: transform)
parent = nodesMap.parents(parent!).first
}

View File

@ -7,9 +7,9 @@
//
public enum Easing {
case Ease
case Linear
case EaseIn
case EaseOut
case EaseInOut
case ease
case linear
case easeIn
case easeOut
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)
}
func applyTransform(transform: Transform) -> Rect {
func applyTransform(_ transform: Transform) -> Rect {
// TODO: Rewrite using math
let cgTransform = RenderUtils.mapTransform(transform)
return Rect(cgRect: CGRectApplyAffineTransform(self.cgRect(), cgTransform))
return Rect(cgRect: self.cgRect().applying(cgTransform))
}
public func description() -> String {

View File

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

View File

@ -1,5 +1,5 @@
import Foundation
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 {
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),
m12: self.m12.interpolate(endValue.m12, 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 minY = p.y
var maxX = minX
var maxY = minY
for t in 0.0.stride(to: 1.0, by: 0.01) {
p = func2d(t: t)
for t in stride(from: 0.0, to: 1.0, by: 0.01) {
p = func2d(t)
if 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 {
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 currentPoint = firstSegmentInfo.1 ?? Point.origin
var cubicBezierPoint: Point?
@ -40,19 +40,19 @@ func pathBounds(path: Path) -> Rect? {
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
let data = segment.data
switch segment.type {
case .m, .M:
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:
return (cubicBounds(data), Point(x: data[4], y: data[5]), Point(x: data[2], y: data[3]))
case .s, .S:
guard let currentPoint = currentPoint else {
return (.None, .None, .None)
return (.none, .none, .none)
}
var p2 = currentPoint
@ -66,17 +66,17 @@ func pathSegmenInfo(segment: PathSegment, currentPoint: Point?, currentBezierPoi
Point(x: data[2], y: data[3]),
Point(x: p2.x, y: p2.y))
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:
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:
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:
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 p1 = Point(x: data[0], y: data[1])
let p2 = Point(x: data[2], y: data[3])
@ -88,7 +88,7 @@ private func cubicBounds(data: [Double]) -> Rect {
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 p1 = Point(x: data[0], y: data[1])

View File

@ -1,14 +1,14 @@
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(
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))
}
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
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()
self.type = .Sequence
self.type = .sequence
self.node = animations.first?.node
self.delay = delay
}
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
animation.stop()
}
}
public override func reverse() -> Animation {
open override func reverse() -> Animation {
var reversedAnimations = [BasicAnimation]()
animations.forEach { animation in
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.progress = progress
@ -39,8 +39,8 @@ internal class AnimationSequence: BasicAnimation {
}
}
public extension SequenceType where Generator.Element: Animation {
public func sequence(delay delay: Double = 0.0) -> Animation {
public extension Sequence where Iterator.Element: Animation {
public func sequence(delay: Double = 0.0) -> Animation {
var sequence = [BasicAnimation]()
self.forEach { animation in

View File

@ -10,21 +10,21 @@ internal class CombineAnimation: BasicAnimation {
super.init()
self.type = .Combine
self.type = .combine
self.node = animations.first?.node
self.delay = delay
}
override func getDuration() -> Double {
if let maxElement = animations.map({ $0.getDuration() }).maxElement() {
if let maxElement = animations.map({ $0.getDuration() }).max() {
return maxElement
}
return 0.0
}
public override func reverse() -> Animation {
open override func reverse() -> Animation {
var reversedAnimations = [BasicAnimation]()
animations.forEach { animation in
reversedAnimations.append(animation.reverse() as! BasicAnimation)
@ -37,15 +37,15 @@ internal class CombineAnimation: BasicAnimation {
return combineReversed
}
public override func stop() {
open override func stop() {
animations.forEach { animation in
animation.stop()
}
}
}
public extension SequenceType where Generator.Element: Animation {
public func combine(delay delay: Double = 0.0) -> Animation {
public extension Sequence where Iterator.Element: Animation {
public func combine(delay: Double = 0.0) -> Animation {
var toCombine = [BasicAnimation]()
self.forEach { animation in
@ -53,4 +53,4 @@ public extension SequenceType where Generator.Element: Animation {
}
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) {
super.init(observableValue: animatedNode.opacityVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
type = .Opacity
type = .opacity
node = animatedNode
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) {
super.init(observableValue: animatedNode.opacityVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
type = .Opacity
type = .opacity
node = animatedNode
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 original = self.timeFactory(node)
return { (t: Double) -> Double in
@ -52,19 +52,19 @@ internal class OpacityAnimation: AnimationImpl<Double> {
public typealias OpacityAnimationDescription = AnimationDescription<Double>
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)
}
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)
}
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))
}
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 {
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)
}
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)
}

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) {
super.init(observableValue: animatedNode.placeVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
type = .AffineTransformation
type = .affineTransformation
node = animatedNode
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) {
super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
type = .AffineTransformation
type = .affineTransformation
node = animatedNode
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 original = self.timeFactory(node)
@ -52,19 +52,19 @@ internal class TransformAnimation: AnimationImpl<Transform> {
public typealias TransformAnimationDescription = AnimationDescription<Transform>
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)
}
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)
}
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))
}
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 {
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)
}
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)
}

View File

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

View File

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

View File

@ -6,10 +6,10 @@ import Macaw
extension Node: Hashable {
public var hashValue: Int {
return unsafeAddressOf(self).hashValue
return Unmanaged.passUnretained(self).toOpaque().hashValue
}
}
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
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 {
return
}
@ -47,13 +47,13 @@ func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animati
}
let layer = animationCache.layerForNode(node, animation: animation)
layer.addAnimation(generatedAnimation, forKey: animation.ID)
layer.add(generatedAnimation, forKey: animation.ID)
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 timeValues = [Double]()
@ -61,7 +61,7 @@ func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps
let step = 1.0 / (duration * Double(fps))
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
if 1.0 - dt < step {
@ -75,11 +75,11 @@ func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
opacityAnimation.fillMode = kCAFillModeForwards
opacityAnimation.removedOnCompletion = false
opacityAnimation.isRemovedOnCompletion = false
opacityAnimation.duration = duration
opacityAnimation.values = opacityValues
opacityAnimation.keyTimes = timeValues
opacityAnimation.keyTimes = timeValues as [NSNumber]?
return opacityAnimation
}

View File

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

View File

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

View File

@ -8,25 +8,25 @@
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 {
disposable.dispose()
}
items = []
}
public func add(item: Disposable) {
open func add(_ item: Disposable) {
items.append(item)
}
}
extension Disposable {
public func addTo(group: GroupDisposable) {
public func addTo(_ group: GroupDisposable) {
group.add(self)
}
}

View File

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

View File

@ -1,7 +1,7 @@
public class PanEvent {
open class PanEvent {
public let dx: Double
public let dy: Double
open let dx: Double
open let dy: Double
init(dx: Double, dy: Double) {
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) {
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) {
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) {
self.location = location

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,13 @@
import Foundation
import RxSwift
public class RadialGradient: Gradient {
open class RadialGradient: Gradient {
public let cx: Double
public let cy: Double
public let fx: Double
public let fy: Double
public let r: Double
open let cx: Double
open let cy: Double
open let fx: Double
open let fy: 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] = []) {
self.cx = cx

View File

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

View File

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

View File

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

View File

@ -1,11 +1,11 @@
import Foundation
import RxSwift
public class Circle: Locus {
open class Circle: Locus {
public let cx: Double
public let cy: Double
public let r: Double
open let cx: Double
open let cy: Double
open let r: Double
public init(cx: Double = 0, cy: Double = 0, r: Double = 0) {
self.cx = cx
@ -14,7 +14,7 @@ public class Circle: Locus {
}
// 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)
}

View File

@ -1,12 +1,12 @@
import Foundation
import RxSwift
public class Ellipse: Locus {
open class Ellipse: Locus {
public let cx: Double
public let cy: Double
public let rx: Double
public let ry: Double
open let cx: Double
open let cy: Double
open let rx: Double
open let ry: Double
public init(cx: Double = 0, cy: Double = 0, rx: Double = 0, ry: Double = 0) {
self.cx = cx
@ -16,7 +16,7 @@ public class Ellipse: Locus {
}
// 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)
}

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 nm21 = t2.m21 * t1.m11 + t2.m22 * t1.m21
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)
}
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 {
return Transform()
}

View File

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

View File

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

View File

@ -1,28 +1,28 @@
import Foundation
import RxSwift
public class Locus {
open class Locus {
public init() {
}
// GENERATED NOT
public func bounds() -> Rect {
open func bounds() -> Rect {
return Rect()
}
// GENERATED NOT
public func stroke(with with: Stroke) -> Shape {
open func stroke(with: Stroke) -> Shape {
return Shape(form: self, stroke: with)
}
// GENERATED NOT
public func fill(with with: Fill) -> Shape {
open func fill(with: Fill) -> Shape {
return Shape(form: self, fill: with)
}
// 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))
}

View File

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

View File

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

View File

@ -1,10 +1,10 @@
import Foundation
import RxSwift
public class PathBuilder {
open class PathBuilder {
public let segment: PathSegment
public let rest: PathBuilder?
open let segment: PathSegment
open let rest: PathBuilder?
public init(segment: PathSegment, rest: PathBuilder? = nil) {
self.segment = segment
@ -12,143 +12,143 @@ public class PathBuilder {
}
// GENERATED NOT
public func moveTo(x x: Double, y: Double) -> PathBuilder {
open func moveTo(x: Double, y: Double) -> PathBuilder {
return M(x, y)
}
// GENERATED NOT
public func lineTo(x x: Double, y: Double) -> PathBuilder {
open func lineTo(x: Double, y: Double) -> PathBuilder {
return L(x, y)
}
// 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)
}
// 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)
}
// 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)
}
// GENERATED NOT
public func close() -> PathBuilder {
open func close() -> PathBuilder {
return Z()
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// GENERATED NOT
public func h(x: Double) -> PathBuilder {
open func h(_ x: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .h, data: [x]), rest: self)
}
// GENERATED NOT
public func H(x: Double) -> PathBuilder {
open func H(_ x: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .H, data: [x]), rest: self)
}
// GENERATED NOT
public func v(y: Double) -> PathBuilder {
open func v(_ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .v, data: [y]), rest: self)
}
// GENERATED NOT
public func V(y: Double) -> PathBuilder {
open func V(_ y: Double) -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .V, data: [y]), rest: self)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// GENERATED NOT
public func Z() -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .Z), rest: self)
open func Z() -> PathBuilder {
return PathBuilder(segment: PathSegment(type: .z), rest: self)
}
// GENERATED NOT
public func build() -> Path {
open func build() -> Path {
var segments : [PathSegment] = []
var builder : PathBuilder? = self
while(builder != nil) {
segments.append(builder!.segment)
builder = builder!.rest
}
return Path(segments: segments.reverse())
return Path(segments: segments.reversed())
}
// 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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,57 +22,57 @@ public final class Transform {
}
// 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,
dx: dx * m11 + dy * m21 + self.dx, dy: dx * m12 + dy * m22 + self.dy)
}
// 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)
}
// 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,
m21: m11 * shx + m21, m22: m12 * shx + m22, dx: dx, dy: dy)
}
// GENERATED NOT
public func rotate(angle angle: Double) -> Transform {
public func rotate(angle: Double) -> Transform {
let asin = sin(angle); let acos = cos(angle)
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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
}
// 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)
return Transform(m11: acos, m12: asin, m21: -asin, m22: acos)
}
// 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)
}

View File

@ -1,9 +1,9 @@
import Foundation
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] = []) {
self.contents = ObservableArray<Node>(array: contents)
@ -22,12 +22,12 @@ public class Group: Node {
override internal func bounds() -> Rect? {
guard let firstPos = contents.first?.place else {
return .None
return .none
}
guard var union = contents.first?.bounds()?.applyTransform(firstPos) else {
return .None
return .none
}
contents.forEach { node in

View File

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

View File

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

View File

@ -1,30 +1,30 @@
import Foundation
import RxSwift
public class Shape: Node {
open class Shape: Node {
public let formVar: Variable<Locus>
public var form: Locus {
open let formVar: Variable<Locus>
open var form: Locus {
get { return formVar.value }
set(val) { formVar.value = val }
}
public let fillVar: Variable<Fill?>
public var fill: Fill? {
open let fillVar: Variable<Fill?>
open var fill: Fill? {
get { return fillVar.value }
set(val) { fillVar.value = val }
}
public let strokeVar: Variable<Stroke?>
public var stroke: Stroke? {
open let strokeVar: Variable<Stroke?>
open var stroke: Stroke? {
get { return strokeVar.value }
set(val) { strokeVar.value = val }
}
public let onTap = PublishSubject<TapEvent>()
public let onPan = PublishSubject<PanEvent>()
public let onRotate = PublishSubject<RotateEvent>()
public let onPinch = PublishSubject<PinchEvent>()
open let onTap = PublishSubject<TapEvent>()
open let onPan = PublishSubject<PanEvent>()
open let onRotate = PublishSubject<RotateEvent>()
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] = []) {
self.formVar = Variable<Locus>(form)

View File

@ -1,34 +1,34 @@
import UIKit
import RxSwift
public class Text: Node {
open class Text: Node {
public let textVar: Variable<String>
public var text: String {
open let textVar: Variable<String>
open var text: String {
get { return textVar.value }
set(val) { textVar.value = val }
}
public let fontVar: Variable<Font?>
public var font: Font? {
open let fontVar: Variable<Font?>
open var font: Font? {
get { return fontVar.value }
set(val) { fontVar.value = val }
}
public let fillVar: Variable<Fill>
public var fill: Fill {
open let fillVar: Variable<Fill>
open var fill: Fill {
get { return fillVar.value }
set(val) { fillVar.value = val }
}
public let alignVar: Variable<Align>
public var align: Align {
open let alignVar: Variable<Align>
open var align: Align {
get { return alignVar.value }
set(val) { alignVar.value = val }
}
public let baselineVar: Variable<Baseline>
public var baseline: Baseline {
open let baselineVar: Variable<Baseline>
open var baseline: Baseline {
get { return baselineVar.value }
set(val) { baselineVar.value = val }
}
@ -57,14 +57,14 @@ public class Text: Node {
if let customFont = UIFont(name: f.name, size: CGFloat(f.size)) {
font = customFont
} else {
font = UIFont.systemFontOfSize(CGFloat(f.size))
font = UIFont.systemFont(ofSize: CGFloat(f.size))
}
} else {
font = UIFont.systemFontOfSize(UIFont.systemFontSize())
font = UIFont.systemFont(ofSize: UIFont.systemFontSize)
}
var stringAttributes: [String: AnyObject] = [:]
stringAttributes[NSFontAttributeName] = font
let size = (text as NSString).sizeWithAttributes(stringAttributes)
let size = (text as NSString).size(attributes: stringAttributes)
if (self.baseline == Baseline.bottom) {
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
private var renderers: [NodeRenderer] = []
fileprivate var renderers: [NodeRenderer] = []
init(group: Group, ctx: RenderContext, animationCache: AnimationCache) {
self.group = group
@ -24,27 +24,27 @@ class GroupRenderer: NodeRenderer {
return group
}
override func doRender(force: Bool, opacity: Double) {
override func doRender(_ force: Bool, opacity: Double) {
renderers.forEach { renderer in
CGContextSaveGState(ctx.cgContext!)
CGContextConcatCTM(ctx.cgContext!, RenderUtils.mapTransform(renderer.node().place))
ctx.cgContext!.saveGState()
ctx.cgContext!.concatenate(RenderUtils.mapTransform(renderer.node().place))
setClip(renderer.node())
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]()
renderers.forEach { renderer in
if let inverted = renderer.node().place.invert() {
CGContextSaveGState(ctx.cgContext!)
CGContextConcatCTM(ctx.cgContext!, RenderUtils.mapTransform(renderer.node().place))
let translatedLocation = CGPointApplyAffineTransform(location, RenderUtils.mapTransform(inverted))
ctx.cgContext!.saveGState()
ctx.cgContext!.concatenate(RenderUtils.mapTransform(renderer.node().place))
let translatedLocation = location.applying(RenderUtils.mapTransform(inverted))
setClip(renderer.node())
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
touchedShapes.appendContentsOf(renderer.detectTouches(offsetLocation))
CGContextRestoreGState(ctx.cgContext!)
touchedShapes.append(contentsOf: renderer.detectTouches(offsetLocation))
ctx.cgContext!.restoreGState()
}
}
@ -59,20 +59,20 @@ class GroupRenderer: NodeRenderer {
// TODO: extract to NodeRenderer
// TODO: path support
func setClip(node: Node) {
func setClip(_ node: Node) {
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] = [:]
for renderer in renderers {
nodeToRenderer[renderer.node()] = renderer
}
self.renderers = []
for node in group.contents {
if let renderer = nodeToRenderer.removeValueForKey(node) {
if let renderer = nodeToRenderer.removeValue(forKey: node) {
self.renderers.append(renderer)
} else {
self.renderers.append(RenderUtils.createNodeRenderer(node, context: ctx, animationCache: animationCache))

View File

@ -25,14 +25,14 @@ class ImageRenderer: NodeRenderer {
observe(image.hVar)
}
override func doRender(force: Bool, opacity: Double) {
override func doRender(_ force: Bool, opacity: Double) {
if let uiimage = UIImage(named: image.src) {
let imageSize = uiimage.size
var w = CGFloat(image.w)
var h = CGFloat(image.h)
var rect: CGRect
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 {
if (w == 0) {
w = imageSize.width * h / imageSize.height
@ -44,25 +44,25 @@ class ImageRenderer: NodeRenderer {
rect = calculateMeetAspectRatio(image, size: imageSize)
case AspectRatio.slice:
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:
rect = CGRectMake(0, 0, w, h)
rect = CGRect(x: 0, y: 0, width: w, height: h)
}
}
CGContextScaleCTM(ctx.cgContext!, 1.0, -1.0)
CGContextTranslateCTM(ctx.cgContext!, 0.0, -1.0 * rect.height)
ctx.cgContext!.scaleBy(x: 1.0, y: -1.0)
ctx.cgContext!.translateBy(x: 0.0, y: -1.0 * rect.height)
CGContextSetAlpha(ctx.cgContext!, CGFloat(opacity))
CGContextDrawImage(ctx.cgContext!, rect, uiimage.CGImage!)
ctx.cgContext!.setAlpha(CGFloat(opacity))
ctx.cgContext!.draw(uiimage.cgImage!, in: rect)
}
}
override func detectTouches(location: CGPoint) -> [Shape] {
override func detectTouches(_ location: CGPoint) -> [Shape] {
return []
}
private func calculateMeetAspectRatio(image: Image, size: CGSize) -> CGRect {
fileprivate func calculateMeetAspectRatio(_ image: Image, size: CGSize) -> CGRect {
let w = CGFloat(image.w)
let h = CGFloat(image.h)
// destination and source aspect ratios
@ -97,10 +97,10 @@ class ImageRenderer: NodeRenderer {
case Align.max:
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 h = CGFloat(image.h)
var srcX = CGFloat(0)
@ -135,6 +135,6 @@ class ImageRenderer: NodeRenderer {
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
private let onNodeChange: (Any) -> Void
private let disposables = GroupDisposable()
private var active = false
fileprivate let onNodeChange: (Any) -> Void
fileprivate let disposables = GroupDisposable()
fileprivate var active = false
let animationCache: AnimationCache
init(node: Node, ctx: RenderContext, animationCache: AnimationCache) {
@ -26,27 +26,27 @@ class NodeRenderer {
observe(node().effectVar)
}
func observe<E>(variable: Variable<E>) {
func observe<E>(_ variable: Variable<E>) {
observe(variable.asObservable())
}
func observe<E>(observable: Observable<E>) {
func observe<E>(_ observable: Observable<E>) {
addDisposable(observable.subscribeNext(onNodeChange))
}
func addDisposable(disposable: Disposable) {
func addDisposable(_ disposable: Disposable) {
disposable.addTo(disposables)
}
public func dispose() {
open func dispose() {
removeObservers()
}
public func node() -> Node {
open func node() -> Node {
fatalError("Unsupported")
}
final public func render(force: Bool, opacity: Double) {
final public func render(_ force: Bool, opacity: Double) {
if animationCache.isAnimating(node()) {
self.removeObservers()
if (!force) {
@ -58,26 +58,26 @@ class NodeRenderer {
doRender(force, opacity: opacity)
}
func doRender(force: Bool, opacity: Double) {
func doRender(_ force: Bool, opacity: Double) {
fatalError("Unsupported")
}
public func detectTouches(location: CGPoint) -> [Shape] {
open func detectTouches(_ location: CGPoint) -> [Shape] {
return []
}
private func addObservers() {
fileprivate func addObservers() {
if (!active) {
active = true
doAddObservers()
}
}
private func removeObservers() {
fileprivate func removeObservers() {
if (active) {
active = false
disposables.dispose()
}
}
}
}

View File

@ -2,44 +2,44 @@ import Foundation
import UIKit
class RenderUtils {
class func mapColor(color: Color) -> CGColor {
class func mapColor(_ color: Color) -> CGColor {
let red = CGFloat(Double(color.r()) / 255.0)
let green = CGFloat(Double(color.g()) / 255.0)
let blue = CGFloat(Double(color.b()) / 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),
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 {
case LineJoin.round?: return CGLineJoin.Round
case LineJoin.bevel?: return CGLineJoin.Bevel
default: return CGLineJoin.Miter
case LineJoin.round?: return CGLineJoin.round
case LineJoin.bevel?: return CGLineJoin.bevel
default: return CGLineJoin.miter
}
}
class func mapLineCap(cap: LineCap?) -> CGLineCap {
class func mapLineCap(_ cap: LineCap?) -> CGLineCap {
switch cap {
case LineCap.round?: return CGLineCap.Round
case LineCap.square?: return CGLineCap.Square
default: return CGLineCap.Butt
case LineCap.round?: return CGLineCap.round
case LineCap.square?: return CGLineCap.square
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)))
for (index, item) in dashes.enumerate() {
for (index, item) in dashes.enumerated() {
p[index] = CGFloat(item)
}
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 {
return GroupRenderer(group: group, ctx: context, animationCache: animationCache)
} else if let shape = node as? Shape {
@ -52,7 +52,7 @@ class RenderUtils {
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)
}
}
}

View File

@ -21,61 +21,61 @@ class ShapeRenderer: NodeRenderer {
observe(shape.strokeVar)
}
override func doRender(force: Bool, opacity: Double) {
override func doRender(_ force: Bool, opacity: Double) {
setGeometry(shape.form, ctx: ctx.cgContext!)
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]()
setGeometry(shape.form, ctx: ctx.cgContext!)
var drawingMode: CGPathDrawingMode? = nil
if let _ = shape.stroke, _ = shape.fill {
drawingMode = .FillStroke
if let _ = shape.stroke, let _ = shape.fill {
drawingMode = .fillStroke
} else if let _ = shape.stroke {
drawingMode = .Stroke
drawingMode = .stroke
} else if let _ = shape.fill {
drawingMode = .Fill
drawingMode = .fill
}
var contains = false
if let mode = drawingMode {
contains = CGContextPathContainsPoint(ctx.cgContext!, location, mode)
contains = ctx.cgContext!.pathContains(location, mode: mode)
}
if contains {
touchedShapes.append(shape)
}
// Prepare for next figure hittesting - clear current context path
CGContextBeginPath(ctx.cgContext!)
ctx.cgContext!.beginPath()
return touchedShapes
}
private func setGeometry(locus: Locus, ctx: CGContext) {
fileprivate func setGeometry(_ locus: Locus, ctx: CGContext) {
if let rect = locus as? Rect {
CGContextAddRect(ctx, newCGRect(rect))
ctx.addRect(newCGRect(rect))
} 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:
UIRectCorner.AllCorners, cornerRadii: corners).CGPath
CGContextAddPath(ctx, path)
UIRectCorner.allCorners, cornerRadii: corners).cgPath
ctx.addPath(path)
} else if let circle = locus as? Circle {
let cx = circle.cx
let cy = circle.cy
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 {
let cx = ellipse.cx
let cy = ellipse.cy
let rx = ellipse.rx
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 {
if arc.ellipse.rx == arc.ellipse.ry {
// Only circle arc supported for now
CGContextAddPath(ctx, toBezierPath(arc).CGPath)
ctx.addPath(toBezierPath(arc).cgPath)
} else {
// http://stackoverflow.com/questions/11365775/how-to-draw-an-elliptical-arc-with-coregraphics
// input parameters
@ -85,60 +85,60 @@ class ShapeRenderer: NodeRenderer {
let r = CGFloat(ellipse.rx)
let scale = CGFloat(ellipse.ry / ellipse.rx)
let path = CGPathCreateMutable()
var t = CGAffineTransformMakeTranslation(CGFloat(ellipse.cx), CGFloat(ellipse.cy))
t = CGAffineTransformConcat(CGAffineTransformMakeScale(1.0, scale), t);
let path = CGMutablePath()
var t = CGAffineTransform(translationX: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
t = CGAffineTransform(scaleX: 1.0, y: scale).concatenating(t);
CGPathAddArc(path, &t, 0, 0, r, startAngle, endAngle, false)
CGContextAddPath(ctx, path)
ctx.addPath(path)
}
} else if let point = locus as? Point {
let path = UIBezierPath()
path.moveToPoint(CGPointMake(CGFloat(point.x), CGFloat(point.y)))
path.addLineToPoint(CGPointMake(CGFloat(point.x), CGFloat(point.y)))
CGContextAddPath(ctx, path.CGPath)
path.move(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
path.addLine(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
ctx.addPath(path.cgPath)
} else if let line = locus as? Line {
let path = UIBezierPath()
path.moveToPoint(CGPointMake(CGFloat(line.x1), CGFloat(line.y1)))
path.addLineToPoint(CGPointMake(CGFloat(line.x2), CGFloat(line.y2)))
CGContextAddPath(ctx, path.CGPath)
path.move(to: CGPoint(x: CGFloat(line.x1), y: CGFloat(line.y1)))
path.addLine(to: CGPoint(x: CGFloat(line.x2), y: CGFloat(line.y2)))
ctx.addPath(path.cgPath)
} else if let polygon = locus as? Polygon {
let path = toBezierPath(polygon.points)
path.closePath()
CGContextAddPath(ctx, path.CGPath)
path.close()
ctx.addPath(path.cgPath)
} 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 {
CGContextAddPath(ctx, toBezierPath(path).CGPath)
ctx.addPath(toBezierPath(path).cgPath)
} else {
print("Unsupported locus: \(locus)")
}
}
private func toBezierPath(arc: Arc) -> UIBezierPath {
fileprivate func toBezierPath(_ arc: Arc) -> UIBezierPath {
let shift = CGFloat(arc.shift)
let end = shift + CGFloat(arc.extent)
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)
}
private func toBezierPath(points: [Double]) -> UIBezierPath {
let parts = 0.stride(to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) }
fileprivate func toBezierPath(_ points: [Double]) -> UIBezierPath {
let parts = stride(from: 0, to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) }
let path = UIBezierPath()
var first = true
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) {
path.moveToPoint(point)
path.move(to: point)
first = false
} else {
path.addLineToPoint(point)
path.addLine(to: point)
}
}
return path
}
private func toBezierPath(path: Path) -> UIBezierPath {
fileprivate func toBezierPath(_ path: Path) -> UIBezierPath {
let bezierPath = UIBezierPath()
var currentPoint: CGPoint?
@ -146,119 +146,119 @@ class ShapeRenderer: NodeRenderer {
var quadrPoint: CGPoint?
var initialPoint: CGPoint?
func M(x: Double, y: Double) {
let point = CGPointMake(CGFloat(x), CGFloat(y))
bezierPath.moveToPoint(point)
func M(_ x: Double, y: Double) {
let point = CGPoint(x: CGFloat(x), y: CGFloat(y))
bezierPath.move(to: point)
setInitPoint(point)
}
func m(x: Double, y: Double) {
func m(_ x: Double, y: Double) {
if let cur = currentPoint {
let next = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y)
bezierPath.moveToPoint(next)
let next = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
bezierPath.move(to: next)
setInitPoint(next)
} else {
M(x, y: y)
}
}
func L(x: Double, y: Double) {
lineTo(CGPointMake(CGFloat(x), CGFloat(y)))
func L(_ x: Double, y: Double) {
lineTo(CGPoint(x: CGFloat(x), y: CGFloat(y)))
}
func l(x: Double, y: Double) {
func l(_ x: Double, y: Double) {
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 {
L(x, y: y)
}
}
func H(x: Double) {
func H(_ x: Double) {
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 {
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 {
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 {
lineTo(CGPointMake(CGFloat(cur.x), CGFloat(y) + cur.y))
lineTo(CGPoint(x: CGFloat(cur.x), y: CGFloat(y) + cur.y))
}
}
func lineTo(p: CGPoint) {
bezierPath.addLineToPoint(p)
func lineTo(_ p: CGPoint) {
bezierPath.addLine(to: 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 {
let endPoint = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y)
let controlPoint1 = CGPointMake(CGFloat(x1) + cur.x, CGFloat(y1) + cur.y)
let controlPoint2 = CGPointMake(CGFloat(x2) + cur.x, CGFloat(y2) + cur.y)
bezierPath.addCurveToPoint(endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
let endPoint = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
let controlPoint1 = CGPoint(x: CGFloat(x1) + cur.x, y: CGFloat(y1) + cur.y)
let controlPoint2 = CGPoint(x: CGFloat(x2) + cur.x, y: CGFloat(y2) + cur.y)
bezierPath.addCurve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
setCubicPoint(endPoint, cubic: controlPoint2)
}
}
func C(x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
let endPoint = CGPointMake(CGFloat(x), CGFloat(y))
let controlPoint1 = CGPointMake(CGFloat(x1), CGFloat(y1))
let controlPoint2 = CGPointMake(CGFloat(x2), CGFloat(y2))
bezierPath.addCurveToPoint(endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
func C(_ x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
let endPoint = CGPoint(x: CGFloat(x), y: CGFloat(y))
let controlPoint1 = CGPoint(x: CGFloat(x1), y: CGFloat(y1))
let controlPoint2 = CGPoint(x: CGFloat(x2), y: CGFloat(y2))
bezierPath.addCurve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: 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 {
let nextCubic = CGPointMake(CGFloat(x2) + cur.x, CGFloat(y2) + cur.y)
let next = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y)
let nextCubic = CGPoint(x: CGFloat(x2) + cur.x, y: CGFloat(y2) + cur.y)
let next = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
var xy1: CGPoint?
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 {
xy1 = cur
}
bezierPath.addCurveToPoint(next, controlPoint1: xy1!, controlPoint2: nextCubic)
bezierPath.addCurve(to: next, controlPoint1: xy1!, controlPoint2: 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 {
let nextCubic = CGPointMake(CGFloat(x2), CGFloat(y2))
let next = CGPointMake(CGFloat(x), CGFloat(y))
let nextCubic = CGPoint(x: CGFloat(x2), y: CGFloat(y2))
let next = CGPoint(x: CGFloat(x), y: CGFloat(y))
var xy1: CGPoint?
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 {
xy1 = cur
}
bezierPath.addCurveToPoint(next, controlPoint1: xy1!, controlPoint2: nextCubic)
bezierPath.addCurve(to: next, controlPoint1: xy1!, controlPoint2: 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 {
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 {
let x1 = Double(cur.x)
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);
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
let extent = CGFloat(startAngle)
let end = extent + CGFloat(arcAngle)
let center = CGPointMake(CGFloat(x + w / 2), CGFloat(y + h / 2))
bezierPath.addArcWithCenter(center, radius: CGFloat(w / 2), startAngle: extent, endAngle: end, clockwise: true)
let center = CGPoint(x: CGFloat(x + w / 2), y: CGFloat(y + h / 2))
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
if let cur = currentPoint {
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 {
lineTo(initPoint)
}
bezierPath.closePath()
bezierPath.close()
}
func setCubicPoint(p: CGPoint, cubic: CGPoint) {
func setCubicPoint(_ p: CGPoint, cubic: CGPoint) {
currentPoint = p
cubicPoint = cubic
quadrPoint = nil
}
func setInitPoint(p: CGPoint) {
func setInitPoint(_ p: CGPoint) {
setPoint(p)
initialPoint = p
}
func setPoint(p: CGPoint) {
func setPoint(_ p: CGPoint) {
currentPoint = p
cubicPoint = nil
quadrPoint = nil
@ -343,27 +343,27 @@ class ShapeRenderer: NodeRenderer {
switch part.type {
case .M:
M(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2))
data.removeSubrange((0 ..< 2))
while data.count >= 2 {
L(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2))
data.removeSubrange((0 ..< 2))
}
case .m:
m(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2))
data.removeSubrange((0 ..< 2))
while data.count >= 2 {
l(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2))
data.removeSubrange((0 ..< 2))
}
case .L:
while data.count >= 2 {
L(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2))
data.removeSubrange((0 ..< 2))
}
case .l:
while data.count >= 2 {
l(data[0], y: data[1])
data.removeRange(Range(start: 0, end: 2))
data.removeSubrange((0 ..< 2))
}
case .H:
H(data[0])
@ -376,22 +376,22 @@ class ShapeRenderer: NodeRenderer {
case .C:
while data.count >= 6 {
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:
while data.count >= 6 {
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:
while data.count >= 4 {
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:
while data.count >= 4 {
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:
let flags = numToBools(data[3])
@ -399,7 +399,7 @@ class ShapeRenderer: NodeRenderer {
case .a:
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])
case .Z:
case .z:
Z()
default:
fatalError("Unknown segment: \(part.type)")
@ -408,54 +408,54 @@ class ShapeRenderer: NodeRenderer {
return bezierPath
}
private func numToBools(num: Double) -> [Bool] {
fileprivate func numToBools(_ num: Double) -> [Bool] {
let val: Int = Int(num);
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))
}
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
if fill is Gradient || stroke?.fill is Gradient {
shouldStrokePath = true
}
if let fill = fill, stroke = stroke {
let path = CGContextCopyPath(ctx!)
if let fill = fill, let stroke = stroke {
let path = ctx!.path
setFill(fill, ctx: ctx, opacity: opacity)
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
}
if let fill = fill {
setFill(fill, ctx: ctx, opacity: opacity)
CGContextDrawPath(ctx!, .Fill)
ctx!.drawPath(using: .fill)
return
}
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
}
CGContextSetLineWidth(ctx!, 2.0)
CGContextSetStrokeColorWithColor(ctx!, UIColor.blackColor().CGColor)
CGContextDrawPath(ctx!, .Stroke)
ctx!.setLineWidth(2.0)
ctx!.setStrokeColor(UIColor.black.cgColor)
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 {
return
}
if let fillColor = fill as? Color {
let color = RenderUtils.applyOpacity(fillColor, opacity: opacity)
CGContextSetFillColorWithColor(ctx!, RenderUtils.mapColor(color))
ctx!.setFillColor(RenderUtils.mapColor(color))
} else if let gradient = fill as? Gradient {
drawGradient(gradient, ctx: ctx, opacity: opacity)
} 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) {
if let path = path where shouldStrokePath {
CGContextAddPath(ctx!, path)
fileprivate func drawWithStroke(_ stroke: Stroke, ctx: CGContext?, opacity: Double, shouldStrokePath: Bool = false, path: CGPath? = nil, mode: CGPathDrawingMode) {
if let path = path , shouldStrokePath {
ctx!.addPath(path)
}
setStrokeAttributes(stroke, ctx: ctx)
@ -476,42 +476,42 @@ class ShapeRenderer: NodeRenderer {
colorStroke(stroke, ctx: ctx, opacity: opacity)
}
if shouldStrokePath {
CGContextStrokePath(ctx!)
ctx!.strokePath()
} else {
CGContextDrawPath(ctx!, mode)
ctx!.drawPath(using: mode)
}
}
private func setStrokeAttributes(stroke: Stroke, ctx: CGContext?) {
CGContextSetLineWidth(ctx!, CGFloat(stroke.width))
CGContextSetLineJoin(ctx!, RenderUtils.mapLineJoin(stroke.join))
CGContextSetLineCap(ctx!, RenderUtils.mapLineCap(stroke.cap))
fileprivate func setStrokeAttributes(_ stroke: Stroke, ctx: CGContext?) {
ctx!.setLineWidth(CGFloat(stroke.width))
ctx!.setLineJoin(RenderUtils.mapLineJoin(stroke.join))
ctx!.setLineCap(RenderUtils.mapLineCap(stroke.cap))
let dashes = stroke.dashes
if !dashes.isEmpty {
let dashPointer = RenderUtils.mapDash(dashes)
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 {
return
}
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 {
return
}
CGContextReplacePathWithStrokedPath(ctx!)
ctx!.replacePathWithStrokedPath()
drawGradient(gradient, ctx: ctx, opacity: opacity)
}
private func drawGradient(gradient: Gradient, ctx: CGContext?, opacity: Double) {
CGContextSaveGState(ctx!)
fileprivate func drawGradient(_ gradient: Gradient, ctx: CGContext?, opacity: Double) {
ctx!.saveGState()
var colors: [CGColor] = []
var stops: [CGFloat] = []
for stop in gradient.stops {
@ -521,22 +521,22 @@ class ShapeRenderer: NodeRenderer {
}
if let gradient = gradient as? LinearGradient {
var start = CGPointMake(CGFloat(gradient.x1), CGFloat(gradient.y1))
var end = CGPointMake(CGFloat(gradient.x2), CGFloat(gradient.y2))
var start = CGPoint(x: CGFloat(gradient.x1), y: CGFloat(gradient.y1))
var end = CGPoint(x: CGFloat(gradient.x2), y: CGFloat(gradient.y2))
if !gradient.userSpace {
let bounds = CGContextGetPathBoundingBox(ctx!)
start = CGPointMake(start.x * bounds.width + bounds.minX, start.y * bounds.height + bounds.minY)
end = CGPointMake(end.x * bounds.width + bounds.minX, end.y * bounds.height + bounds.minY)
let bounds = ctx!.boundingBoxOfPath
start = CGPoint(x: start.x * bounds.width + bounds.minX, y: start.y * bounds.height + bounds.minY)
end = CGPoint(x: end.x * bounds.width + bounds.minX, y: end.y * bounds.height + bounds.minY)
}
CGContextClip(ctx!)
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
CGContextDrawLinearGradient(ctx!, cgGradient!, start, end, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
ctx!.clip()
let cgGradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: stops)
ctx!.drawLinearGradient(cgGradient!, start: start, end: end, options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
} else if let gradient = gradient as? RadialGradient {
var innerCenter = CGPointMake(CGFloat(gradient.fx), CGFloat(gradient.fy))
var outerCenter = CGPointMake(CGFloat(gradient.cx), CGFloat(gradient.cy))
var innerCenter = CGPoint(x: CGFloat(gradient.fx), y: CGFloat(gradient.fy))
var outerCenter = CGPoint(x: CGFloat(gradient.cx), y: CGFloat(gradient.cy))
var radius = CGFloat(gradient.r)
if !gradient.userSpace {
var bounds = CGContextGetPathBoundingBox(ctx!)
var bounds = ctx!.boundingBoxOfPath
var scaleX: CGFloat = 1
var scaleY: CGFloat = 1
if bounds.width > bounds.height {
@ -544,18 +544,18 @@ class ShapeRenderer: NodeRenderer {
} else {
scaleX = bounds.width / bounds.height
}
CGContextScaleCTM(ctx!, scaleX, scaleY)
bounds = CGContextGetPathBoundingBox(ctx!)
innerCenter = CGPointMake(innerCenter.x * bounds.width + bounds.minX, innerCenter.y * bounds.height + bounds.minY)
outerCenter = CGPointMake(outerCenter.x * bounds.width + bounds.minX, outerCenter.y * bounds.height + bounds.minY)
ctx!.scaleBy(x: scaleX, y: scaleY)
bounds = ctx!.boundingBoxOfPath
innerCenter = CGPoint(x: innerCenter.x * bounds.width + bounds.minX, y: innerCenter.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)
}
CGContextClip(ctx!)
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
CGContextDrawRadialGradient(ctx!, cgGradient!, innerCenter, 0, outerCenter, radius, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
ctx!.clip()
let cgGradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: stops)
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)
}
override func doRender(force: Bool, opacity: Double) {
override func doRender(_ force: Bool, opacity: Double) {
let message = text.text
var font: UIFont
if let textFont = text.font {
if let customFont = UIFont(name: textFont.name, size: CGFloat(textFont.size)) {
font = customFont
} else {
font = UIFont.systemFontOfSize(CGFloat(textFont.size))
font = UIFont.systemFont(ofSize: CGFloat(textFont.size))
}
} else {
font = UIFont.systemFontOfSize(UIFont.systemFontSize())
font = UIFont.systemFont(ofSize: UIFont.systemFontSize)
}
// positive NSBaselineOffsetAttributeName values don't work, couldn't find why
// for now move the rect itself
@ -41,25 +41,25 @@ class TextRenderer: NodeRenderer {
color = RenderUtils.applyOpacity(color, opacity: opacity)
let textAttributes = [
NSFontAttributeName: font,
NSForegroundColorAttributeName: getTextColor(color)]
let textSize = NSString(string: text.text).sizeWithAttributes(textAttributes)
NSForegroundColorAttributeName: getTextColor(color)] as [String : Any]
let textSize = NSString(string: text.text).size(attributes: textAttributes)
guard let cgContext = ctx.cgContext else {
return
}
UIGraphicsPushContext(cgContext)
message.drawInRect(CGRectMake(calculateAlignmentOffset(text, font: font), calculateBaselineOffset(text, font: font),
CGFloat(textSize.width), CGFloat(textSize.height)), withAttributes: textAttributes)
message.draw(in: CGRect(x: calculateAlignmentOffset(text, font: font), y: calculateBaselineOffset(text, font: font),
width: CGFloat(textSize.width), height: CGFloat(textSize.height)), withAttributes: textAttributes)
UIGraphicsPopContext()
}
}
override func detectTouches(location: CGPoint) -> [Shape] {
override func detectTouches(_ location: CGPoint) -> [Shape] {
return []
}
private func calculateBaselineOffset(text: Text, font: UIFont) -> CGFloat {
fileprivate func calculateBaselineOffset(_ text: Text, font: UIFont) -> CGFloat {
var baselineOffset = CGFloat(0)
switch text.baseline {
case Baseline.alphabetic:
@ -74,11 +74,11 @@ class TextRenderer: NodeRenderer {
return -baselineOffset
}
private func calculateAlignmentOffset(text: Text, font: UIFont) -> CGFloat {
fileprivate func calculateAlignmentOffset(_ text: Text, font: UIFont) -> CGFloat {
let textAttributes = [
NSFontAttributeName: font
]
let textSize = NSString(string: text.text).sizeWithAttributes(textAttributes)
let textSize = NSString(string: text.text).size(attributes: textAttributes)
var alignmentOffset = CGFloat(0)
switch text.align {
case Align.mid:
@ -91,10 +91,10 @@ class TextRenderer: NodeRenderer {
return -alignmentOffset
}
private func getTextColor(fill: Fill) -> UIColor {
fileprivate func getTextColor(_ fill: Fill) -> UIColor {
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 {
private static let transformAttributePattern = "([a-z]+)\\(((\\-?\\d+\\.?\\d*\\s*,?\\s*)+)\\)"
private static let transformPattern = "\\-?\\d+\\.?\\d*"
private static let textElementPattern = "<text.*?>((?s:.*))<\\/text>"
fileprivate static let transformAttributePattern = "([a-z]+)\\(((\\-?\\d+\\.?\\d*\\s*,?\\s*)+)\\)"
fileprivate static let transformPattern = "\\-?\\d+\\.?\\d*"
fileprivate static let textElementPattern = "<text.*?>((?s:.*))<\\/text>"
private static var transformMatcher: NSRegularExpression?
private static var transformAttributeMatcher: NSRegularExpression?
private static var textElementMatcher: NSRegularExpression?
fileprivate static var transformMatcher: NSRegularExpression?
fileprivate static var transformAttributeMatcher: NSRegularExpression?
fileprivate static var textElementMatcher: NSRegularExpression?
class func getTransformAttributeMatcher() -> NSRegularExpression? {
if self.transformAttributeMatcher == nil {
do {
self.transformAttributeMatcher = try NSRegularExpression(pattern: transformAttributePattern, options: .CaseInsensitive)
self.transformAttributeMatcher = try NSRegularExpression(pattern: transformAttributePattern, options: .caseInsensitive)
} catch {
}
@ -24,7 +24,7 @@ class SVGParserRegexHelper {
class func getTransformMatcher() -> NSRegularExpression? {
if self.transformMatcher == nil {
do {
self.transformMatcher = try NSRegularExpression(pattern: transformPattern, options: .CaseInsensitive)
self.transformMatcher = try NSRegularExpression(pattern: transformPattern, options: .caseInsensitive)
} catch {
}
@ -35,7 +35,7 @@ class SVGParserRegexHelper {
class func getTextElementMatcher() -> NSRegularExpression? {
if self.textElementMatcher == nil {
do {
self.textElementMatcher = try NSRegularExpression(pattern: textElementPattern, options: .CaseInsensitive)
self.textElementMatcher = try NSRegularExpression(pattern: textElementPattern, options: .caseInsensitive)
} catch {
}

View File

@ -17,15 +17,15 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
var completion: ((Bool) -> Void)?
/// startTime: animation start date
private var startTime: NSDate!
private var animationDuration: NSTimeInterval!
private var animatingTimer: NSTimer!
fileprivate var startTime: Date!
fileprivate var animationDuration: TimeInterval!
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)
var animating: ((CGFloat) -> Void)? {
willSet {
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
*/
func animationDidStart(theAnimation: CAAnimation) {
func animationDidStart(_ theAnimation: CAAnimation) {
start?()
if animating != nil {
animationDuration = theAnimation.duration
startTime = NSDate()
NSRunLoop.currentRunLoop().addTimer(animatingTimer, forMode: NSDefaultRunLoopMode)
startTime = Date()
RunLoop.current.add(animatingTimer, forMode: RunLoopMode.defaultRunLoopMode)
}
}
@ -50,7 +50,7 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
- parameter theAnimation: the animation about to end
- 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)
animatingTimer?.invalidate()
}
@ -60,8 +60,8 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
- parameter timer: timer
*/
func animationIsAnimating(timer: NSTimer) {
let progress = CGFloat(NSDate().timeIntervalSinceDate(startTime) / animationDuration)
func animationIsAnimating(_ timer: Timer) {
let progress = CGFloat(Date().timeIntervalSince(startTime) / animationDuration)
if progress <= 1.0 {
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 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
addAnimation(anim, forKey: key)
add(anim, forKey: key)
}
}

View File

@ -1,7 +1,7 @@
import Foundation
extension NSTimer {
extension Timer {
/**
Creates and schedules a one-time `NSTimer` instance.
@ -11,10 +11,10 @@ extension NSTimer {
- 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 timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer
}
@ -29,10 +29,10 @@ extension NSTimer {
- 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 timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer
}
}

View File

@ -5,10 +5,10 @@ import UIKit
/// 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.
///
public class MacawView: UIView {
open class MacawView: UIView {
/// Scene root node
public var node: Node = Group() {
open var node: Node = Group() {
willSet {
nodesMap.remove(node)
}
@ -26,7 +26,7 @@ public class MacawView: UIView {
}
}
override public var frame: CGRect {
override open var frame: CGRect {
didSet {
super.frame = frame
@ -40,7 +40,7 @@ public class MacawView: UIView {
}
}
override public func didMoveToSuperview() {
override open func didMoveToSuperview() {
super.didMoveToSuperview()
if !frameSetFirstTime {
@ -51,7 +51,7 @@ public class MacawView: UIView {
animationProducer.addStoredAnimations(node)
}
private var selectedShape: Shape? = nil
fileprivate var selectedShape: Shape? = nil
var context: RenderContext!
var renderer: NodeRenderer?
@ -86,26 +86,26 @@ public class MacawView: UIView {
self.init(node: Group(), coder: aDecoder)
}
override public func drawRect(rect: CGRect) {
override open func draw(_ rect: CGRect) {
self.context.cgContext = UIGraphicsGetCurrentContext()
CGContextSaveGState(self.context.cgContext!)
CGContextConcatCTM(self.context.cgContext!, RenderUtils.mapTransform(node.place))
self.context.cgContext!.saveGState()
self.context.cgContext!.concatenate(RenderUtils.mapTransform(node.place))
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
if let inverted = node.place.invert() {
for touch in touches {
let location = touch.locationInView(self)
let translatedLocation = CGPointApplyAffineTransform(location, RenderUtils.mapTransform(inverted))
let location = touch.location(in: self)
let translatedLocation = location.applying(RenderUtils.mapTransform(inverted))
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
CGContextSaveGState(self.context.cgContext!)
CGContextConcatCTM(self.context.cgContext!, RenderUtils.mapTransform(node.place))
self.context.cgContext!.saveGState()
self.context.cgContext!.concatenate(RenderUtils.mapTransform(node.place))
let shapes = renderer?.detectTouches(offsetLocation)
CGContextRestoreGState(self.context.cgContext!)
self.context.cgContext!.restoreGState()
self.selectedShape = shapes?.first
if let shape = self.selectedShape {
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) {
var translation = recognizer.translationInView(self)
recognizer.setTranslation(CGPointZero, inView: self)
func handlePan(_ recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: self)
recognizer.setTranslation(CGPoint.zero, in: self)
if let shape = self.selectedShape {
// get the rotation and scale of the shape and apply to the translation
let transform = shape.place
let rotation = -CGFloat(atan2f(Float(transform.m12), Float(transform.m11)))
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)))
}
}
func handleRotation(recognizer: UIRotationGestureRecognizer) {
func handleRotation(_ recognizer: UIRotationGestureRecognizer) {
let rotation = Double(recognizer.rotation)
recognizer.rotation = 0
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)
recognizer.scale = 1
if let shape = self.selectedShape {

View File

@ -8,7 +8,7 @@ class NodesMap {
var map = [Node: MacawView]()
// MARK: - Macaw View
func add(node: Node, view: MacawView) {
func add(_ node: Node, view: MacawView) {
map[node] = view
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]
}
func remove(node: Node) {
map.removeValueForKey(node)
parentsMap.removeValueForKey(node)
func remove(_ node: Node) {
map.removeValue(forKey: node)
parentsMap.removeValue(forKey: node)
}
// MARK: - Parents
func add(node: Node, parent: Node) {
func add(_ node: Node, parent: Node) {
if var nodesSet = parentsMap[node] {
nodesSet.insert(parent)
} else {
@ -37,7 +37,7 @@ class NodesMap {
}
}
func parents(node: Node) -> [Node] {
func parents(_ node: Node) -> [Node] {
guard let nodesSet = parentsMap[node] else {
return []
}

View File

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