1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-21 09:59:10 +03:00

Merge commit 'c78b3e9605d1e50fed488f98214cbaff8e3808f9' into task/svgViewBox

This commit is contained in:
Alisa Mylnikova 2018-04-09 18:22:27 +07:00
commit 052003ade0
41 changed files with 891 additions and 883 deletions

View File

@ -14,6 +14,7 @@ disabled_rules:
- strict_fileprivate
- sorted_imports
- identifier_name # Disabled due to a lot of one symbol identifiers
- let_var_whitespace
# Temporary disabled
- explicit_type_interface
- line_length
@ -66,7 +67,6 @@ opt_in_rules:
- legacy_cggeometry_functions
- legacy_constant
- legacy_nsgeometry_functions
- let_var_whitespace
- mark
- multiline_parameters
- multiple_closures_with_trailing_closure

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
let animationProducer = AnimationProducer()

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
public extension Rect {

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
class AnimationCache {

View File

@ -9,9 +9,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
func addMorphingAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) {

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
func addOpacityAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) {

View File

@ -9,9 +9,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
func addShapeAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) {

View File

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

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
func addTransformAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) {

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
open class LinearGradient: Gradient {
@ -22,33 +22,33 @@ open class LinearGradient: Gradient {
)
}
public convenience init(degree: Double = 0, from: Color, to: Color) {
self.init(degree: degree, stops: [Stop(offset: 0, color: from), Stop(offset: 1, color: to)])
public convenience init(degree: Double = 0, from: Color, to: Color) {
self.init(degree: degree, stops: [Stop(offset: 0, color: from), Stop(offset: 1, color: to)])
}
public init(degree: Double = 0, stops: [Stop]) {
public init(degree: Double = 0, stops: [Stop]) {
let rad = degree * .pi / 180
var v = [0, 0, cos(rad), sin(rad)]
let mmax = 1 / max(abs(v[2]), abs(v[3]))
v[2] *= mmax
v[3] *= mmax
if (v[2] < 0) {
if v[2] < 0 {
v[0] = -v[2]
v[2] = 0
}
if (v[3] < 0) {
if v[3] < 0 {
v[1] = -v[3]
v[3] = 0
}
self.x1 = v[0]
self.y1 = v[1]
self.x2 = v[2]
self.y2 = v[3]
super.init(
userSpace: false,
stops: stops
)
}
super.init(
userSpace: false,
stops: stops
)
}
}

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
open class RadialGradient: Gradient {

View File

@ -155,7 +155,7 @@ open class PathBuilder {
}
return Path(segments: segments.reversed())
}
// GENERATED NOT
fileprivate func boolToNum(_ value: Bool) -> Double {
return value ? 1 : 0

View File

@ -114,13 +114,13 @@ open class Group: Node {
return shouldCheck
}
override func shouldCheckForLongTap() -> Bool {
var shouldCheck = super.shouldCheckForLongTap()
contents.forEach { node in
shouldCheck = shouldCheck || node.shouldCheckForLongTap()
}
return shouldCheck
}

View File

@ -1,11 +1,11 @@
import Foundation
#if os(OSX)
import AppKit
import AppKit
#endif
#if os(iOS)
import UIKit
import UIKit
#endif
open class Image: Node {
@ -160,9 +160,9 @@ open class Image: Node {
// General case
#if os(iOS)
return MImage(named: src)
return MImage(named: src)
#elseif os(OSX)
return MImage(named: NSImage.Name(rawValue: src))
return MImage(named: NSImage.Name(rawValue: src))
#endif
}
}

View File

@ -64,12 +64,12 @@ open class Node: Drawable {
var touchPressedHandlers = [ChangeHandler<TouchEvent>]()
var touchMovedHandlers = [ChangeHandler<TouchEvent>]()
var touchReleasedHandlers = [ChangeHandler<TouchEvent>]()
var prevTouchCount: Int = 0
var prevTouchTimer: Timer?
var isLongTapInProgress = false
var tapHandlers = [Int : [ChangeHandler<TapEvent>]]()
var tapHandlers = [Int: [ChangeHandler<TapEvent>]]()
var longTapHandlers = [ChangeHandler<TapEvent>]()
var panHandlers = [ChangeHandler<PanEvent>]()
var rotateHandlers = [ChangeHandler<RotateEvent>]()
@ -130,16 +130,16 @@ open class Node: Drawable {
self?.tapHandlers[tapCount]?.remove(at: index)
}
}
@discardableResult public func onLongTap(_ f: @escaping (TapEvent) -> Void) -> Disposable {
let handler = ChangeHandler<TapEvent>(f)
longTapHandlers.append(handler)
return Disposable { [weak self] in
guard let index = self?.longTapHandlers.index(of: handler) else {
return
}
self?.longTapHandlers.remove(at: index)
}
}
@ -196,9 +196,9 @@ open class Node: Drawable {
func handleTouchMoved(_ event: TouchEvent) {
touchMovedHandlers.forEach { handler in handler.handle(event) }
}
// MARK: - Multiple tap handling
func handleTap( _ event: TapEvent ) {
if isLongTapInProgress {
prevTouchCount = 0
@ -209,32 +209,32 @@ open class Node: Drawable {
prevTouchTimer = nil
}
prevTouchCount += 1
for tapCount in tapHandlers.keys {
if tapCount > prevTouchCount { // wait some more - there is a recognizer for even more taps
prevTouchTimer = Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(onTouchTimer), userInfo: event, repeats: false)
return
}
}
for (tapCount, handlers) in tapHandlers {
if tapCount == prevTouchCount { // nothing to wait for - max tap count reached
handlers.forEach { handler in handler.handle(event) }
prevTouchCount = 0
}
}
}
@objc func onTouchTimer(timer: Timer) {
if isLongTapInProgress {
prevTouchCount = 0
return
}
for touchCount in tapHandlers.keys.sorted(by: {$0>$1}) {
for touchCount in tapHandlers.keys.sorted(by: { $0>$1 }) {
if touchCount <= prevTouchCount, let event = timer.userInfo as? TapEvent {
// no more taps coming, settle for next best thing
for _ in 0..<prevTouchCount/touchCount { // might need to call it multiple times
for _ in 0..<prevTouchCount / touchCount { // might need to call it multiple times
tapHandlers[touchCount]?.forEach { handler in handler.handle(event) }
}
break
@ -242,9 +242,9 @@ open class Node: Drawable {
}
prevTouchCount = 0
}
// MARK: - Helpers
func handleLongTap( _ event: TapEvent, touchBegan: Bool ) {
isLongTapInProgress = touchBegan
if touchBegan {
@ -280,7 +280,7 @@ open class Node: Drawable {
func shouldCheckForTap() -> Bool {
return !tapHandlers.isEmpty
}
func shouldCheckForLongTap() -> Bool {
return !longTapHandlers.isEmpty
}

View File

@ -9,26 +9,26 @@
class SceneUtils {
static func shapeCopy(from: Shape) -> Shape {
let shape = Shape(form: from.form,
fill: from.fill,
stroke: from.stroke,
place: from.place,
opaque: from.opaque,
opacity: from.opacity,
clip: from.clip,
effect: from.effect,
visible: from.visible,
tag: from.tag)
shape.touchPressedHandlers = from.touchPressedHandlers
shape.touchMovedHandlers = from.touchMovedHandlers
shape.touchReleasedHandlers = from.touchReleasedHandlers
shape.tapHandlers = from.tapHandlers
fill: from.fill,
stroke: from.stroke,
place: from.place,
opaque: from.opaque,
opacity: from.opacity,
clip: from.clip,
effect: from.effect,
visible: from.visible,
tag: from.tag)
shape.touchPressedHandlers = from.touchPressedHandlers
shape.touchMovedHandlers = from.touchMovedHandlers
shape.touchReleasedHandlers = from.touchReleasedHandlers
shape.tapHandlers = from.tapHandlers
shape.longTapHandlers = from.longTapHandlers
shape.panHandlers = from.panHandlers
shape.rotateHandlers = from.rotateHandlers
shape.pinchHandlers = from.pinchHandlers
return shape
shape.panHandlers = from.panHandlers
shape.rotateHandlers = from.rotateHandlers
shape.pinchHandlers = from.pinchHandlers
return shape
}
}

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
open class Text: Node {
@ -85,7 +85,7 @@ open class Text: Node {
h: size.height.doubleValue
)
}
fileprivate func getWeight(_ weight: String) -> MFont.Weight {
switch weight {
case "normal":

View File

@ -9,80 +9,80 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
public typealias MRectCorner = UIRectCorner
public typealias MFont = UIFont
public typealias MColor = UIColor
public typealias MEvent = UIEvent
public typealias MTouch = UITouch
public typealias MImage = UIImage
public typealias MBezierPath = UIBezierPath
public typealias MGestureRecognizer = UIGestureRecognizer
public typealias MGestureRecognizerState = UIGestureRecognizerState
public typealias MGestureRecognizerDelegate = UIGestureRecognizerDelegate
public typealias MTapGestureRecognizer = UITapGestureRecognizer
public typealias MLongPressGestureRecognizer = UILongPressGestureRecognizer
public typealias MPanGestureRecognizer = UIPanGestureRecognizer
public typealias MPinchGestureRecognizer = UIPinchGestureRecognizer
public typealias MRotationGestureRecognizer = UIRotationGestureRecognizer
public typealias MScreen = UIScreen
public typealias MViewContentMode = UIViewContentMode
public typealias MRectCorner = UIRectCorner
public typealias MFont = UIFont
public typealias MColor = UIColor
public typealias MEvent = UIEvent
public typealias MTouch = UITouch
public typealias MImage = UIImage
public typealias MBezierPath = UIBezierPath
public typealias MGestureRecognizer = UIGestureRecognizer
public typealias MGestureRecognizerState = UIGestureRecognizerState
public typealias MGestureRecognizerDelegate = UIGestureRecognizerDelegate
public typealias MTapGestureRecognizer = UITapGestureRecognizer
public typealias MLongPressGestureRecognizer = UILongPressGestureRecognizer
public typealias MPanGestureRecognizer = UIPanGestureRecognizer
public typealias MPinchGestureRecognizer = UIPinchGestureRecognizer
public typealias MRotationGestureRecognizer = UIRotationGestureRecognizer
public typealias MScreen = UIScreen
public typealias MViewContentMode = UIViewContentMode
extension MTapGestureRecognizer {
func mNumberOfTouches() -> Int {
return numberOfTouches
extension MTapGestureRecognizer {
func mNumberOfTouches() -> Int {
return numberOfTouches
}
}
extension MPanGestureRecognizer {
func mNumberOfTouches() -> Int {
return numberOfTouches
}
func mLocationOfTouch(_ touch: Int, inView: UIView?) -> CGPoint {
return super.location(ofTouch: touch, in: inView)
}
}
extension MRotationGestureRecognizer {
final var mRotation: CGFloat {
get {
return rotation
}
set {
rotation = newValue
}
}
}
extension MPinchGestureRecognizer {
var mScale: CGFloat {
get {
return scale
}
set {
scale = newValue
}
}
extension MPanGestureRecognizer {
func mNumberOfTouches() -> Int {
return numberOfTouches
}
func mLocationOfTouch(_ touch: Int, inView: UIView?) -> CGPoint {
return super.location(ofTouch: touch, in: inView)
}
func mLocationOfTouch(_ touch: Int, inView: UIView?) -> CGPoint {
return super.location(ofTouch: touch, in: inView)
}
}
extension MRotationGestureRecognizer {
final var mRotation: CGFloat {
get {
return rotation
}
set {
rotation = newValue
}
}
extension MFont {
class var mSystemFontSize: CGFloat {
return UIFont.systemFontSize
}
}
extension MPinchGestureRecognizer {
var mScale: CGFloat {
get {
return scale
}
set {
scale = newValue
}
}
func mLocationOfTouch(_ touch: Int, inView: UIView?) -> CGPoint {
return super.location(ofTouch: touch, in: inView)
}
}
extension MFont {
class var mSystemFontSize: CGFloat {
return UIFont.systemFontSize
}
}
extension UIScreen {
var mScale: CGFloat {
return self.scale
}
extension UIScreen {
var mScale: CGFloat {
return self.scale
}
}
#endif

View File

@ -9,42 +9,42 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
func MGraphicsGetCurrentContext() -> CGContext? {
return UIGraphicsGetCurrentContext()
}
func MGraphicsGetCurrentContext() -> CGContext? {
return UIGraphicsGetCurrentContext()
}
func MGraphicsGetImageFromCurrentImageContext() -> MImage! {
return UIGraphicsGetImageFromCurrentImageContext()
}
func MGraphicsGetImageFromCurrentImageContext() -> MImage! {
return UIGraphicsGetImageFromCurrentImageContext()
}
func MGraphicsPushContext(_ context: CGContext) {
UIGraphicsPushContext(context)
}
func MGraphicsPushContext(_ context: CGContext) {
UIGraphicsPushContext(context)
}
func MGraphicsPopContext() {
UIGraphicsPopContext()
}
func MGraphicsPopContext() {
UIGraphicsPopContext()
}
func MGraphicsEndImageContext() {
UIGraphicsEndImageContext()
}
func MGraphicsEndImageContext() {
UIGraphicsEndImageContext()
}
func MImagePNGRepresentation(_ image: MImage) -> Data? {
return UIImagePNGRepresentation(image)
}
func MImagePNGRepresentation(_ image: MImage) -> Data? {
return UIImagePNGRepresentation(image)
}
func MImageJPEGRepresentation(_ image: MImage, _ quality: CGFloat = 0.8) -> Data? {
return UIImageJPEGRepresentation(image, quality)
}
func MImageJPEGRepresentation(_ image: MImage, _ quality: CGFloat = 0.8) -> Data? {
return UIImageJPEGRepresentation(image, quality)
}
func MMainScreen() -> MScreen? {
return MScreen.main
}
func MMainScreen() -> MScreen? {
return MScreen.main
}
func MGraphicsBeginImageContextWithOptions(_ size: CGSize, _ opaque: Bool, _ scale: CGFloat) {
UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
}
func MGraphicsBeginImageContextWithOptions(_ size: CGSize, _ opaque: Bool, _ scale: CGFloat) {
UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
}
#endif

View File

@ -7,33 +7,33 @@
//
#if os(iOS)
import UIKit
import UIKit
class MDisplayLink: MDisplayLinkProtocol {
private var displayLink: CADisplayLink?
private var onUpdate: (() -> Void)?
class MDisplayLink: MDisplayLinkProtocol {
private var displayLink: CADisplayLink?
private var onUpdate: (() -> Void)?
// MARK: - Lifecycle
deinit {
displayLink?.invalidate()
}
// MARK: - MDisplayLinkProtocol
func startUpdates(_ onUpdate: @escaping () -> Void) {
self.onUpdate = onUpdate
displayLink = CADisplayLink(target: self, selector: #selector(updateHandler))
displayLink?.frameInterval = 1
displayLink?.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
}
func invalidate() {
displayLink?.invalidate()
}
// MARK: - Private
@objc func updateHandler() {
onUpdate?()
}
// MARK: - Lifecycle
deinit {
displayLink?.invalidate()
}
// MARK: - MDisplayLinkProtocol
func startUpdates(_ onUpdate: @escaping () -> Void) {
self.onUpdate = onUpdate
displayLink = CADisplayLink(target: self, selector: #selector(updateHandler))
displayLink?.frameInterval = 1
displayLink?.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
}
func invalidate() {
displayLink?.invalidate()
}
// MARK: - Private
@objc func updateHandler() {
onUpdate?()
}
}
#endif

View File

@ -9,88 +9,88 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
open class MView: UIView, Touchable {
var mLayer: CALayer? {
return self.layer
}
var mGestureRecognizers: [MGestureRecognizer]? {
return self.gestureRecognizers
}
func removeGestureRecognizers() {
self.gestureRecognizers?.removeAll()
}
open override func touchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesBegan(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesBegan(touchPoints)
}
open override func touchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesMoved(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
self.mTouchesMoved(touchPoints)
}
open override func touchesEnded(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesEnded(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesEnded(touchPoints)
}
override open func touchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesCancelled(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesCancelled(touchPoints)
}
func mTouchesBegan(_ touches: [MTouchEvent]) {
}
func mTouchesMoved(_ touches: [MTouchEvent]) {
}
func mTouchesEnded(_ touches: [MTouchEvent]) {
}
func mTouchesCancelled(_ touches: [MTouchEvent]) {
}
open class MView: UIView, Touchable {
var mLayer: CALayer? {
return self.layer
}
var mGestureRecognizers: [MGestureRecognizer]? {
return self.gestureRecognizers
}
func removeGestureRecognizers() {
self.gestureRecognizers?.removeAll()
}
open override func touchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesBegan(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesBegan(touchPoints)
}
open override func touchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesMoved(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
self.mTouchesMoved(touchPoints)
}
open override func touchesEnded(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesEnded(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesEnded(touchPoints)
}
override open func touchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesCancelled(touches, with: event)
let touchPoints = touches.map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesCancelled(touchPoints)
}
func mTouchesBegan(_ touches: [MTouchEvent]) {
}
func mTouchesMoved(_ touches: [MTouchEvent]) {
}
func mTouchesEnded(_ touches: [MTouchEvent]) {
}
func mTouchesCancelled(_ touches: [MTouchEvent]) {
}
}
#endif

View File

@ -9,135 +9,135 @@
import Foundation
#if os(OSX)
import Cocoa
import Quartz
import Cocoa
import Quartz
public typealias MFont = NSFont
public typealias MColor = NSColor
public typealias MEvent = NSEvent
public typealias MTouch = NSTouch
public typealias MImage = NSImage
public typealias MBezierPath = NSBezierPath
public typealias MGestureRecognizer = NSGestureRecognizer
public typealias MGestureRecognizerState = NSGestureRecognizer.State
public typealias MGestureRecognizerDelegate = NSGestureRecognizerDelegate
public typealias MTapGestureRecognizer = NSClickGestureRecognizer
public typealias MLongPressGestureRecognizer = NSPressGestureRecognizer
public typealias MPanGestureRecognizer = NSPanGestureRecognizer
public typealias MPinchGestureRecognizer = NSMagnificationGestureRecognizer
public typealias MRotationGestureRecognizer = NSRotationGestureRecognizer
public typealias MScreen = NSScreen
public typealias MFont = NSFont
public typealias MColor = NSColor
public typealias MEvent = NSEvent
public typealias MTouch = NSTouch
public typealias MImage = NSImage
public typealias MBezierPath = NSBezierPath
public typealias MGestureRecognizer = NSGestureRecognizer
public typealias MGestureRecognizerState = NSGestureRecognizer.State
public typealias MGestureRecognizerDelegate = NSGestureRecognizerDelegate
public typealias MTapGestureRecognizer = NSClickGestureRecognizer
public typealias MLongPressGestureRecognizer = NSPressGestureRecognizer
public typealias MPanGestureRecognizer = NSPanGestureRecognizer
public typealias MPinchGestureRecognizer = NSMagnificationGestureRecognizer
public typealias MRotationGestureRecognizer = NSRotationGestureRecognizer
public typealias MScreen = NSScreen
extension MGestureRecognizer {
var cancelsTouchesInView: Bool {
get {
return false
} set { }
extension MGestureRecognizer {
var cancelsTouchesInView: Bool {
get {
return false
} set { }
}
}
extension MTapGestureRecognizer {
func mNumberOfTouches() -> Int {
return 1
}
}
extension MPanGestureRecognizer {
func mNumberOfTouches() -> Int {
return 1
}
func mLocationOfTouch(_ touch: Int, inView: NSView?) -> NSPoint {
return super.location(in: inView)
}
}
extension MRotationGestureRecognizer {
var velocity: CGFloat {
return 0.1
}
var mRotation: CGFloat {
get {
return -rotation
}
set {
rotation = -newValue
}
}
}
extension MPinchGestureRecognizer {
var mScale: CGFloat {
get {
return magnification + 1.0
}
set {
magnification = newValue - 1.0
}
}
extension MTapGestureRecognizer {
func mNumberOfTouches() -> Int {
return 1
}
func mLocationOfTouch(_ touch: Int, inView view: NSView?) -> NSPoint {
return super.location(in: view)
}
}
extension NSFont {
var lineHeight: CGFloat {
return self.boundingRectForFont.size.height
}
extension MPanGestureRecognizer {
func mNumberOfTouches() -> Int {
return 1
}
func mLocationOfTouch(_ touch: Int, inView: NSView?) -> NSPoint {
return super.location(in: inView)
}
class var mSystemFontSize: CGFloat {
return NSFont.systemFontSize
}
}
extension MRotationGestureRecognizer {
var velocity: CGFloat {
return 0.1
}
var mRotation: CGFloat {
get {
return -rotation
}
set {
rotation = -newValue
}
}
extension NSScreen {
var mScale: CGFloat {
return self.backingScaleFactor
}
}
extension MPinchGestureRecognizer {
var mScale: CGFloat {
get {
return magnification + 1.0
}
set {
magnification = newValue - 1.0
}
}
func mLocationOfTouch(_ touch: Int, inView view: NSView?) -> NSPoint {
return super.location(in: view)
}
extension NSImage {
var cgImage: CGImage? {
return self.cgImage(forProposedRect: nil, context: nil, hints: nil)
}
}
extension NSFont {
var lineHeight: CGFloat {
return self.boundingRectForFont.size.height
}
extension NSTouch {
func location(in view: NSView) -> NSPoint {
let n = self.normalizedPosition
let b = view.bounds
return NSPoint(x: b.origin.x + b.size.width * n.x, y: b.origin.y + b.size.height * n.y)
}
}
class var mSystemFontSize: CGFloat {
return NSFont.systemFontSize
}
extension NSString {
@nonobjc
func size(attributes attrs: [NSAttributedStringKey: Any]? = nil) -> NSSize {
return size(withAttributes: attrs)
}
}
extension NSScreen {
var mScale: CGFloat {
return self.backingScaleFactor
}
}
func MMainScreen() -> MScreen? {
return MScreen.main
}
extension NSImage {
var cgImage: CGImage? {
return self.cgImage(forProposedRect: nil, context: nil, hints: nil)
}
}
extension MBezierPath {
func apply(_ transform: CGAffineTransform) {
let affineTransform = AffineTransform(
m11: transform.a,
m12: transform.b,
m21: transform.c,
m22: transform.d,
tX: transform.tx,
tY: transform.ty
)
extension NSTouch {
func location(in view: NSView) -> NSPoint {
let n = self.normalizedPosition
let b = view.bounds
return NSPoint(x: b.origin.x + b.size.width * n.x, y: b.origin.y + b.size.height * n.y)
}
}
extension NSString {
@nonobjc
func size(attributes attrs: [NSAttributedStringKey: Any]? = nil) -> NSSize {
return size(withAttributes: attrs)
}
}
func MMainScreen() -> MScreen? {
return MScreen.main
}
extension MBezierPath {
func apply(_ transform: CGAffineTransform) {
let affineTransform = AffineTransform(
m11: transform.a,
m12: transform.b,
m21: transform.c,
m22: transform.d,
tX: transform.tx,
tY: transform.ty
)
self.transform(using: affineTransform)
}
self.transform(using: affineTransform)
}
}
#endif

View File

@ -9,87 +9,87 @@
import Foundation
#if os(OSX)
import AppKit
import AppKit
private var imageContextStack: [CGFloat] = []
private var imageContextStack: [CGFloat] = []
func MGraphicsGetCurrentContext() -> CGContext? {
return NSGraphicsContext.current?.cgContext
func MGraphicsGetCurrentContext() -> CGContext? {
return NSGraphicsContext.current?.cgContext
}
func MGraphicsPushContext(_ context: CGContext) {
let cx = NSGraphicsContext(cgContext: context, flipped: true)
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.current = cx
}
func MGraphicsPopContext() {
NSGraphicsContext.restoreGraphicsState()
}
func MImagePNGRepresentation(_ image: MImage) -> Data? {
image.lockFocus()
let rep = NSBitmapImageRep(focusedViewRect: NSRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
image.unlockFocus()
return rep?.representation(using: NSBitmapImageRep.FileType.png, properties: [:])
}
func MImageJPEGRepresentation(_ image: MImage, _ quality: CGFloat = 0.9) -> Data? {
image.lockFocus()
let rep = NSBitmapImageRep(focusedViewRect: NSRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
image.unlockFocus()
return rep?.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [NSBitmapImageRep.PropertyKey.compressionFactor: quality])
}
func MGraphicsBeginImageContextWithOptions(_ size: CGSize, _ opaque: Bool, _ scale: CGFloat) {
var scale = scale
if scale == 0.0 {
scale = NSScreen.main?.backingScaleFactor ?? 1.0
}
func MGraphicsPushContext(_ context: CGContext) {
let cx = NSGraphicsContext(cgContext: context, flipped: true)
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.current = cx
}
let width = Int(size.width * scale)
let height = Int(size.height * scale)
func MGraphicsPopContext() {
NSGraphicsContext.restoreGraphicsState()
}
if width > 0 && height > 0 {
imageContextStack.append(scale)
func MImagePNGRepresentation(_ image: MImage) -> Data? {
image.lockFocus()
let rep = NSBitmapImageRep(focusedViewRect: NSRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
image.unlockFocus()
let colorSpace = CGColorSpaceCreateDeviceRGB()
return rep?.representation(using: NSBitmapImageRep.FileType.png, properties: [:])
}
func MImageJPEGRepresentation(_ image: MImage, _ quality: CGFloat = 0.9) -> Data? {
image.lockFocus()
let rep = NSBitmapImageRep(focusedViewRect: NSRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
image.unlockFocus()
return rep?.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [NSBitmapImageRep.PropertyKey.compressionFactor: quality])
}
func MGraphicsBeginImageContextWithOptions(_ size: CGSize, _ opaque: Bool, _ scale: CGFloat) {
var scale = scale
if scale == 0.0 {
scale = NSScreen.main?.backingScaleFactor ?? 1.0
guard let ctx = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 4 * width, space: colorSpace, bitmapInfo: (opaque ? CGImageAlphaInfo.noneSkipFirst.rawValue : CGImageAlphaInfo.premultipliedFirst.rawValue)) else {
return
}
let width = Int(size.width * scale)
let height = Int(size.height * scale)
ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height)))
ctx.scaleBy(x: scale, y: scale)
MGraphicsPushContext(ctx)
}
}
if width > 0 && height > 0 {
imageContextStack.append(scale)
func MGraphicsGetImageFromCurrentImageContext() -> MImage? {
if !imageContextStack.isEmpty {
guard let ctx = MGraphicsGetCurrentContext() else {
return nil
}
let colorSpace = CGColorSpaceCreateDeviceRGB()
guard let ctx = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 4 * width, space: colorSpace, bitmapInfo: (opaque ? CGImageAlphaInfo.noneSkipFirst.rawValue : CGImageAlphaInfo.premultipliedFirst.rawValue)) else {
return
}
ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height)))
ctx.scaleBy(x: scale, y: scale)
MGraphicsPushContext(ctx)
let scale = imageContextStack.last!
if let theCGImage = ctx.makeImage() {
let size = CGSize(width: CGFloat(ctx.width) / scale, height: CGFloat(ctx.height) / scale)
let image = NSImage(cgImage: theCGImage, size: size)
return image
}
}
func MGraphicsGetImageFromCurrentImageContext() -> MImage? {
if !imageContextStack.isEmpty {
guard let ctx = MGraphicsGetCurrentContext() else {
return nil
}
return nil
}
let scale = imageContextStack.last!
if let theCGImage = ctx.makeImage() {
let size = CGSize(width: CGFloat(ctx.width) / scale, height: CGFloat(ctx.height) / scale)
let image = NSImage(cgImage: theCGImage, size: size)
return image
}
}
return nil
}
func MGraphicsEndImageContext() {
if imageContextStack.last != nil {
imageContextStack.removeLast()
MGraphicsPopContext()
}
func MGraphicsEndImageContext() {
if imageContextStack.last != nil {
imageContextStack.removeLast()
MGraphicsPopContext()
}
}
#endif

View File

@ -9,162 +9,162 @@
import Foundation
#if os(OSX)
import AppKit
import AppKit
public struct MRectCorner: OptionSet {
public let rawValue: UInt
public struct MRectCorner: OptionSet {
public let rawValue: UInt
public static let none = MRectCorner(rawValue: 0)
public static let topLeft = MRectCorner(rawValue: 1 << 0)
public static let topRight = MRectCorner(rawValue: 1 << 1)
public static let bottomLeft = MRectCorner(rawValue: 1 << 2)
public static let bottomRight = MRectCorner(rawValue: 1 << 3)
public static var allCorners: MRectCorner {
return [.topLeft, .topRight, .bottomLeft, .bottomRight]
}
public init(rawValue: UInt) {
self.rawValue = rawValue
}
public static let none = MRectCorner(rawValue: 0)
public static let topLeft = MRectCorner(rawValue: 1 << 0)
public static let topRight = MRectCorner(rawValue: 1 << 1)
public static let bottomLeft = MRectCorner(rawValue: 1 << 2)
public static let bottomRight = MRectCorner(rawValue: 1 << 3)
public static var allCorners: MRectCorner {
return [.topLeft, .topRight, .bottomLeft, .bottomRight]
}
extension MBezierPath {
public var cgPath: CGPath {
let path = CGMutablePath()
var points = [CGPoint](repeating: .zero, count: 3)
for i in 0 ..< self.elementCount {
let type = self.element(at: i, associatedPoints: &points)
switch type {
case .moveToBezierPathElement:
path.move(to: CGPoint(x: points[0].x, y: points[0].y))
case .lineToBezierPathElement:
path.addLine(to: CGPoint(x: points[0].x, y: points[0].y))
case .curveToBezierPathElement:
path.addCurve(
to: CGPoint(x: points[2].x, y: points[2].y),
control1: CGPoint(x: points[0].x, y: points[0].y),
control2: CGPoint(x: points[1].x, y: points[1].y))
case .closePathBezierPathElement:
path.closeSubpath()
}
}
return path
}
public convenience init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) {
self.init()
self.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)
}
public convenience init(roundedRect rect: NSRect, byRoundingCorners corners: MRectCorner, cornerRadii: NSSize) {
self.init()
let kappa: CGFloat = 1.0 - 0.552228474
let topLeft = rect.origin
let topRight = NSPoint(x: rect.maxX, y: rect.minY)
let bottomRight = NSPoint(x: rect.maxX, y: rect.maxY)
let bottomLeft = NSPoint(x: rect.minX, y: rect.maxY)
if corners.contains(.topLeft) {
move(to: CGPoint(x: topLeft.x + cornerRadii.width, y: topLeft.y))
} else {
move(to: topLeft)
}
if corners.contains(.topRight) {
line(to: CGPoint(x: topRight.x - cornerRadii.width, y: topRight.y))
curve(to: CGPoint(x: topRight.x, y: topRight.y + cornerRadii.height),
controlPoint1: CGPoint(x: topRight.x - cornerRadii.width * kappa, y: topRight.y),
controlPoint2: CGPoint(x: topRight.x, y: topRight.y + cornerRadii.height * kappa))
} else {
line(to: topRight)
}
if corners.contains(.bottomRight) {
line(to: CGPoint(x: bottomRight.x, y: bottomRight.y - cornerRadii.height))
curve(to: CGPoint(x: bottomRight.x - cornerRadii.width, y: bottomRight.y),
controlPoint1: CGPoint(x: bottomRight.x, y: bottomRight.y - cornerRadii.height * kappa),
controlPoint2: CGPoint(x: bottomRight.x - cornerRadii.width * kappa, y: bottomRight.y))
} else {
line(to: bottomRight)
}
if corners.contains(.bottomLeft) {
line(to: CGPoint(x: bottomLeft.x + cornerRadii.width, y: bottomLeft.y))
curve(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y - cornerRadii.height),
controlPoint1: CGPoint(x: bottomLeft.x + cornerRadii.width * kappa, y: bottomLeft.y),
controlPoint2: CGPoint(x: bottomLeft.x, y: bottomLeft.y - cornerRadii.height * kappa))
} else {
line(to: bottomLeft)
}
if corners.contains(.topLeft) {
line(to: CGPoint(x: topLeft.x, y: topLeft.y + cornerRadii.height))
curve(to: CGPoint(x: topLeft.x + cornerRadii.width, y: topLeft.y),
controlPoint1: CGPoint(x: topLeft.x, y: topLeft.y + cornerRadii.height * kappa),
controlPoint2: CGPoint(x: topLeft.x + cornerRadii.width * kappa, y: topLeft.y))
} else {
line(to: topLeft)
}
close()
}
func reversing() -> MBezierPath {
return self.reversed
}
func addLine(to: NSPoint) {
self.line(to: to)
}
func addCurve(to: NSPoint, controlPoint1: NSPoint, controlPoint2: NSPoint) {
self.curve(to: to, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
}
func addQuadCurve(to: NSPoint, controlPoint: NSPoint) {
let QP0 = self.currentPoint
let CP3 = to
let CP1 = CGPoint(
x: QP0.x + ((2.0 / 3.0) * (controlPoint.x - QP0.x)),
y: QP0.y + ((2.0 / 3.0) * (controlPoint.y - QP0.y))
)
let CP2 = CGPoint(
x: to.x + (2.0 / 3.0) * (controlPoint.x - to.x),
y: to.y + (2.0 / 3.0) * (controlPoint.y - to.y)
)
self.addCurve(to: CP3, controlPoint1: CP1, controlPoint2: CP2)
}
func addArc(withCenter: NSPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) {
let startAngleRadian = ((startAngle) * (180.0 / .pi))
let endAngleRadian = ((endAngle) * (180.0 / .pi))
self.appendArc(withCenter: withCenter, radius: radius, startAngle: startAngleRadian, endAngle: endAngleRadian, clockwise: !clockwise)
}
func addPath(path: NSBezierPath!) {
self.append(path)
}
public init(rawValue: UInt) {
self.rawValue = rawValue
}
}
extension MBezierPath {
public var cgPath: CGPath {
let path = CGMutablePath()
var points = [CGPoint](repeating: .zero, count: 3)
for i in 0 ..< self.elementCount {
let type = self.element(at: i, associatedPoints: &points)
switch type {
case .moveToBezierPathElement:
path.move(to: CGPoint(x: points[0].x, y: points[0].y))
case .lineToBezierPathElement:
path.addLine(to: CGPoint(x: points[0].x, y: points[0].y))
case .curveToBezierPathElement:
path.addCurve(
to: CGPoint(x: points[2].x, y: points[2].y),
control1: CGPoint(x: points[0].x, y: points[0].y),
control2: CGPoint(x: points[1].x, y: points[1].y))
case .closePathBezierPathElement:
path.closeSubpath()
}
}
return path
}
public convenience init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) {
self.init()
self.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)
}
public convenience init(roundedRect rect: NSRect, byRoundingCorners corners: MRectCorner, cornerRadii: NSSize) {
self.init()
let kappa: CGFloat = 1.0 - 0.552228474
let topLeft = rect.origin
let topRight = NSPoint(x: rect.maxX, y: rect.minY)
let bottomRight = NSPoint(x: rect.maxX, y: rect.maxY)
let bottomLeft = NSPoint(x: rect.minX, y: rect.maxY)
if corners.contains(.topLeft) {
move(to: CGPoint(x: topLeft.x + cornerRadii.width, y: topLeft.y))
} else {
move(to: topLeft)
}
if corners.contains(.topRight) {
line(to: CGPoint(x: topRight.x - cornerRadii.width, y: topRight.y))
curve(to: CGPoint(x: topRight.x, y: topRight.y + cornerRadii.height),
controlPoint1: CGPoint(x: topRight.x - cornerRadii.width * kappa, y: topRight.y),
controlPoint2: CGPoint(x: topRight.x, y: topRight.y + cornerRadii.height * kappa))
} else {
line(to: topRight)
}
if corners.contains(.bottomRight) {
line(to: CGPoint(x: bottomRight.x, y: bottomRight.y - cornerRadii.height))
curve(to: CGPoint(x: bottomRight.x - cornerRadii.width, y: bottomRight.y),
controlPoint1: CGPoint(x: bottomRight.x, y: bottomRight.y - cornerRadii.height * kappa),
controlPoint2: CGPoint(x: bottomRight.x - cornerRadii.width * kappa, y: bottomRight.y))
} else {
line(to: bottomRight)
}
if corners.contains(.bottomLeft) {
line(to: CGPoint(x: bottomLeft.x + cornerRadii.width, y: bottomLeft.y))
curve(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y - cornerRadii.height),
controlPoint1: CGPoint(x: bottomLeft.x + cornerRadii.width * kappa, y: bottomLeft.y),
controlPoint2: CGPoint(x: bottomLeft.x, y: bottomLeft.y - cornerRadii.height * kappa))
} else {
line(to: bottomLeft)
}
if corners.contains(.topLeft) {
line(to: CGPoint(x: topLeft.x, y: topLeft.y + cornerRadii.height))
curve(to: CGPoint(x: topLeft.x + cornerRadii.width, y: topLeft.y),
controlPoint1: CGPoint(x: topLeft.x, y: topLeft.y + cornerRadii.height * kappa),
controlPoint2: CGPoint(x: topLeft.x + cornerRadii.width * kappa, y: topLeft.y))
} else {
line(to: topLeft)
}
close()
}
func reversing() -> MBezierPath {
return self.reversed
}
func addLine(to: NSPoint) {
self.line(to: to)
}
func addCurve(to: NSPoint, controlPoint1: NSPoint, controlPoint2: NSPoint) {
self.curve(to: to, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
}
func addQuadCurve(to: NSPoint, controlPoint: NSPoint) {
let QP0 = self.currentPoint
let CP3 = to
let CP1 = CGPoint(
x: QP0.x + ((2.0 / 3.0) * (controlPoint.x - QP0.x)),
y: QP0.y + ((2.0 / 3.0) * (controlPoint.y - QP0.y))
)
let CP2 = CGPoint(
x: to.x + (2.0 / 3.0) * (controlPoint.x - to.x),
y: to.y + (2.0 / 3.0) * (controlPoint.y - to.y)
)
self.addCurve(to: CP3, controlPoint1: CP1, controlPoint2: CP2)
}
func addArc(withCenter: NSPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) {
let startAngleRadian = ((startAngle) * (180.0 / .pi))
let endAngleRadian = ((endAngle) * (180.0 / .pi))
self.appendArc(withCenter: withCenter, radius: radius, startAngle: startAngleRadian, endAngle: endAngleRadian, clockwise: !clockwise)
}
func addPath(path: NSBezierPath!) {
self.append(path)
}
}
#endif

View File

@ -9,47 +9,47 @@
import Foundation
#if os(OSX)
import AppKit
import AppKit
public class MDisplayLink: MDisplayLinkProtocol {
private var displayLink: CVDisplayLink?
private var onUpdate: (() -> Void)?
public class MDisplayLink: MDisplayLinkProtocol {
private var displayLink: CVDisplayLink?
private var onUpdate: (() -> Void)?
// MARK: - Lifecycle
deinit {
stop()
// MARK: - Lifecycle
deinit {
stop()
}
// MARK: - MDisplayLinkProtocol
func startUpdates(_ onUpdate: @escaping () -> Void) {
self.onUpdate = onUpdate
if CVDisplayLinkCreateWithActiveCGDisplays(&displayLink) != kCVReturnSuccess {
return
}
// MARK: - MDisplayLinkProtocol
func startUpdates(_ onUpdate: @escaping () -> Void) {
self.onUpdate = onUpdate
CVDisplayLinkSetOutputCallback(displayLink!, { (_, _, _, _, _, userData) -> CVReturn in
if CVDisplayLinkCreateWithActiveCGDisplays(&displayLink) != kCVReturnSuccess {
return
}
let `self` = unsafeBitCast(userData, to: MDisplayLink.self)
`self`.onUpdate?()
CVDisplayLinkSetOutputCallback(displayLink!, { (_, _, _, _, _, userData) -> CVReturn in
return kCVReturnSuccess
}, Unmanaged.passUnretained(self).toOpaque())
let `self` = unsafeBitCast(userData, to: MDisplayLink.self)
`self`.onUpdate?()
return kCVReturnSuccess
}, Unmanaged.passUnretained(self).toOpaque())
if displayLink != nil {
CVDisplayLinkStart(displayLink!)
}
}
func invalidate() {
stop()
}
private func stop() {
if displayLink != nil {
CVDisplayLinkStop(displayLink!)
}
if displayLink != nil {
CVDisplayLinkStart(displayLink!)
}
}
func invalidate() {
stop()
}
private func stop() {
if displayLink != nil {
CVDisplayLinkStop(displayLink!)
}
}
}
#endif

View File

@ -9,189 +9,189 @@
import Foundation
#if os(OSX)
import AppKit
import AppKit
public enum MViewContentMode: Int {
case scaleToFill = 0
case scaleAspectFit = 1
case scaleAspectFill = 2
case redraw = 3
case center = 4
case top = 5
case bottom = 6
case left = 7
case right = 8
case topLeft = 9
case topRight = 10
case bottomLeft = 11
case bottomRight = 12
public enum MViewContentMode: Int {
case scaleToFill = 0
case scaleAspectFit = 1
case scaleAspectFill = 2
case redraw = 3
case center = 4
case top = 5
case bottom = 6
case left = 7
case right = 8
case topLeft = 9
case topRight = 10
case bottomLeft = 11
case bottomRight = 12
}
open class MView: NSView, Touchable {
public override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.wantsLayer = true
}
open class MView: NSView, Touchable {
public override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
public required init?(coder: NSCoder) {
super.init(coder: coder)
self.wantsLayer = true
self.wantsLayer = true
setupMouse()
}
open override var isFlipped: Bool {
return true
}
var mGestureRecognizers: [NSGestureRecognizer]? {
return self.gestureRecognizers
}
open var backgroundColor: MColor? {
get {
return self.layer?.backgroundColor == nil ? nil : NSColor(cgColor: self.layer!.backgroundColor!)
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
self.wantsLayer = true
setupMouse()
}
open override var isFlipped: Bool {
return true
}
var mGestureRecognizers: [NSGestureRecognizer]? {
return self.gestureRecognizers
}
open var backgroundColor: MColor? {
get {
return self.layer?.backgroundColor == nil ? nil : NSColor(cgColor: self.layer!.backgroundColor!)
}
set {
self.layer?.backgroundColor = newValue == nil ? nil : newValue?.cgColor ?? MColor.black.cgColor
}
}
var mLayer: CALayer? {
return self.layer
}
var contentMode: MViewContentMode = .scaleToFill
func removeGestureRecognizers() {
self.gestureRecognizers.removeAll()
}
func didMoveToSuperview() {
super.viewDidMoveToSuperview()
}
func setNeedsDisplay() {
self.setNeedsDisplay(self.bounds)
}
func layoutSubviews() {
super.resizeSubviews(withOldSize: self.bounds.size)
}
// MARK: - Touch pad
open override func touchesBegan(with event: NSEvent) {
super.touchesBegan(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesBegan(touchPoints)
}
open override func touchesEnded(with event: NSEvent) {
super.touchesEnded(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesEnded(touchPoints)
}
open override func touchesMoved(with event: NSEvent) {
super.touchesMoved(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesMoved(touchPoints)
}
open override func touchesCancelled(with event: NSEvent) {
super.touchesCancelled(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesCancelled(touchPoints)
}
// MARK: - Mouse
private func setupMouse() {
subscribeForMouseDown()
subscribeForMouseUp()
subscribeForMouseDragged()
}
private func subscribeForMouseDown() {
NSEvent.addLocalMonitorForEvents(matching: .leftMouseDown) { [weak self] event -> NSEvent? in
self?.handleInput(event: event) { touches in
self?.mTouchesBegan(touches)
}
return event
}
}
private func subscribeForMouseUp() {
NSEvent.addLocalMonitorForEvents(matching: .leftMouseUp) { [weak self] event -> NSEvent? in
self?.handleInput(event: event) { touches in
self?.mTouchesEnded(touches)
}
return event
}
}
private func subscribeForMouseDragged() {
NSEvent.addLocalMonitorForEvents(matching: .leftMouseDragged) { [weak self] event -> NSEvent? in
self?.handleInput(event: event) { touches in
self?.mTouchesMoved(touches)
}
return event
}
}
private func handleInput(event: NSEvent, handler: (_ touches: [MTouchEvent]) -> Void ) {
let location = self.convert(event.locationInWindow, to: .none)
let touchPoint = MTouchEvent(x: Double(location.x), y: Double(location.y), id: 0)
handler([touchPoint])
return
}
// MARK: - Touchable
func mTouchesBegan(_ touches: [MTouchEvent]) {
}
func mTouchesMoved(_ touches: [MTouchEvent]) {
}
func mTouchesEnded(_ touches: [MTouchEvent]) {
}
func mTouchesCancelled(_ touches: [MTouchEvent]) {
set {
self.layer?.backgroundColor = newValue == nil ? nil : newValue?.cgColor ?? MColor.black.cgColor
}
}
var mLayer: CALayer? {
return self.layer
}
var contentMode: MViewContentMode = .scaleToFill
func removeGestureRecognizers() {
self.gestureRecognizers.removeAll()
}
func didMoveToSuperview() {
super.viewDidMoveToSuperview()
}
func setNeedsDisplay() {
self.setNeedsDisplay(self.bounds)
}
func layoutSubviews() {
super.resizeSubviews(withOldSize: self.bounds.size)
}
// MARK: - Touch pad
open override func touchesBegan(with event: NSEvent) {
super.touchesBegan(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesBegan(touchPoints)
}
open override func touchesEnded(with event: NSEvent) {
super.touchesEnded(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesEnded(touchPoints)
}
open override func touchesMoved(with event: NSEvent) {
super.touchesMoved(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesMoved(touchPoints)
}
open override func touchesCancelled(with event: NSEvent) {
super.touchesCancelled(with: event)
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
let location = touch.location(in: self)
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
}
mTouchesCancelled(touchPoints)
}
// MARK: - Mouse
private func setupMouse() {
subscribeForMouseDown()
subscribeForMouseUp()
subscribeForMouseDragged()
}
private func subscribeForMouseDown() {
NSEvent.addLocalMonitorForEvents(matching: .leftMouseDown) { [weak self] event -> NSEvent? in
self?.handleInput(event: event) { touches in
self?.mTouchesBegan(touches)
}
return event
}
}
private func subscribeForMouseUp() {
NSEvent.addLocalMonitorForEvents(matching: .leftMouseUp) { [weak self] event -> NSEvent? in
self?.handleInput(event: event) { touches in
self?.mTouchesEnded(touches)
}
return event
}
}
private func subscribeForMouseDragged() {
NSEvent.addLocalMonitorForEvents(matching: .leftMouseDragged) { [weak self] event -> NSEvent? in
self?.handleInput(event: event) { touches in
self?.mTouchesMoved(touches)
}
return event
}
}
private func handleInput(event: NSEvent, handler: (_ touches: [MTouchEvent]) -> Void ) {
let location = self.convert(event.locationInWindow, to: .none)
let touchPoint = MTouchEvent(x: Double(location.x), y: Double(location.y), id: 0)
handler([touchPoint])
return
}
// MARK: - Touchable
func mTouchesBegan(_ touches: [MTouchEvent]) {
}
func mTouchesMoved(_ touches: [MTouchEvent]) {
}
func mTouchesEnded(_ touches: [MTouchEvent]) {
}
func mTouchesCancelled(_ touches: [MTouchEvent]) {
}
}
#endif

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
class GroupRenderer: NodeRenderer {

View File

@ -1,11 +1,11 @@
import Foundation
#if os(OSX)
import AppKit
import AppKit
#endif
#if os(iOS)
import UIKit
import UIKit
#endif
class ImageRenderer: NodeRenderer {
@ -65,9 +65,9 @@ class ImageRenderer: NodeRenderer {
}
#if os(iOS)
let osImage = MImage(named: image.src)
let osImage = MImage(named: image.src)
#elseif os(OSX)
let osImage = MImage(named: NSImage.Name(rawValue: image.src))
let osImage = MImage(named: NSImage.Name(rawValue: image.src))
#endif
if let mImage = osImage {

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
struct RenderingInterval {

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
class RenderContext {

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
class RenderUtils {
@ -316,14 +316,14 @@ class RenderUtils {
Q(x1 + dx, y1: y1 + dy, x: x + dx, y: y + dy)
}
}
func Q(_ x1: Double, y1: Double, x: Double, y: Double) {
let endPoint = CGPoint(x: x, y: y)
let controlPoint = CGPoint(x: x1, y: y1)
bezierPath.addQuadCurve(to: endPoint, controlPoint: controlPoint)
setQuadrPoint(endPoint, quadr: controlPoint)
}
func t(_ x: Double, y: Double) {
if let cur = currentPoint {
let next = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
@ -337,7 +337,7 @@ class RenderUtils {
setQuadrPoint(next, quadr: quadr!)
}
}
func T(_ x: Double, y: Double) {
if let cur = currentPoint {
let next = CGPoint(x: CGFloat(x), y: CGFloat(y))
@ -367,20 +367,20 @@ class RenderUtils {
// find arc center coordinates and points angles as per
// http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
if (_rx == 0 || _ry == 0) {
if _rx == 0 || _ry == 0 {
L(x, y: y)
} else {
var rx = abs(_rx)
var ry = abs(_ry)
let x1_ = cos(angle) * (x1 - x) / 2 + sin(angle) * (y1 - y) / 2
let y1_ = -1 * sin(angle) * (x1 - x) / 2 + cos(angle) * (y1 - y) / 2
let rCheck = (x1_ * x1_) / (rx * rx) + (y1_ * y1_) / (ry * ry)
if (rCheck > 1) {
if rCheck > 1 {
rx = sqrt(rCheck) * rx
ry = sqrt(rCheck) * ry
}
// make sure the value under the root is positive
let underroot = (rx * rx * ry * ry - rx * rx * y1_ * y1_ - ry * ry * x1_ * x1_)
/ (rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_)
@ -391,18 +391,18 @@ class RenderUtils {
let cy_ = -1 * coef * bigRoot * ry * x1_ / rx
let cx = cos(angle) * cx_ - sin(angle) * cy_ + (x1 + x) / 2
let cy = sin(angle) * cx_ + cos(angle) * cy_ + (y1 + y) / 2
let t1 = calcAngle(ux: 1, uy: 0, vx: (x1_ - cx_) / rx, vy: (y1_ - cy_) / ry)
var delta = calcAngle(ux: (x1_ - cx_) / rx, uy: (y1_ - cy_) / ry, vx: (-x1_ - cx_) / rx, vy: (-y1_ - cy_) / ry)
let pi2 = Double.pi * 2
if (delta > 0) {
if delta > 0 {
delta = delta.truncatingRemainder(dividingBy: pi2)
if (!sweep) {
if !sweep {
delta -= pi2
}
} else if (delta < 0) {
} else if delta < 0 {
delta = -1 * ((-1 * delta).truncatingRemainder(dividingBy: pi2))
if (sweep) {
if sweep {
delta += pi2
}
}
@ -417,20 +417,20 @@ class RenderUtils {
let end = extent + CGFloat(arcAngle)
let cx = CGFloat(x + w / 2)
let cy = CGFloat(y + h / 2)
if (w == h && rotation == 0) {
if w == h && rotation == 0 {
bezierPath.addArc(withCenter: CGPoint(x: cx, y: cy), radius: CGFloat(w / 2), startAngle: extent, endAngle: end, clockwise: arcAngle >= 0)
} else {
let maxSize = CGFloat(max(w, h))
let path = MBezierPath(arcCenter: CGPoint.zero, radius: maxSize / 2, startAngle: extent, endAngle: end, clockwise: arcAngle >= 0)
#if os(iOS)
var transform = CGAffineTransform(translationX: cx, y: cy)
transform = transform.rotated(by: CGFloat(rotation))
path.apply(transform.scaledBy(x: CGFloat(w) / maxSize, y: CGFloat(h) / maxSize))
var transform = CGAffineTransform(translationX: cx, y: cy)
transform = transform.rotated(by: CGFloat(rotation))
path.apply(transform.scaledBy(x: CGFloat(w) / maxSize, y: CGFloat(h) / maxSize))
#elseif os(OSX)
var transform = AffineTransform(translationByX: cx, byY: cy)
transform.rotate(byDegrees: CGFloat(rotation))
path.transform(using: transform)
var transform = AffineTransform(translationByX: cx, byY: cy)
transform.rotate(byDegrees: CGFloat(rotation))
path.transform(using: transform)
#endif
bezierPath.append(path)
@ -552,7 +552,7 @@ class RenderUtils {
}
return bezierPath
}
class func calcAngle(ux: Double, uy: Double, vx: Double, vy: Double) -> Double {
let sign = copysign(1, ux * vy - uy * vx)
let value = (ux * vx + uy * vy) / (sqrt(ux * ux + uy * uy) * sqrt(vx * vx + vy * vy))

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
class ShapeRenderer: NodeRenderer {
@ -36,7 +36,7 @@ class ShapeRenderer: NodeRenderer {
return
}
if (shape.fill != nil || shape.stroke != nil) {
if shape.fill != nil || shape.stroke != nil {
setGeometry(shape.form, ctx: ctx.cgContext!)
drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity)
}

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
class TextRenderer: NodeRenderer {
@ -97,7 +97,7 @@ class TextRenderer: NodeRenderer {
guard #available(iOS 9.0, macOS 10.11, *) else {
// This case should never happen, since the deployment target is set to iOS 9.0/macOS 10.11.
// However it is needed for the Swift Package Manager to work accordingly.
return .none
return .none
}
switch weight {
case "normal":
@ -152,9 +152,9 @@ class TextRenderer: NodeRenderer {
if let color = fill as? Color {
#if os(iOS)
return MColor(cgColor: RenderUtils.mapColor(color))
return MColor(cgColor: RenderUtils.mapColor(color))
#elseif os(OSX)
return MColor(cgColor: RenderUtils.mapColor(color)) ?? .black
return MColor(cgColor: RenderUtils.mapColor(color)) ?? .black
#endif
}

View File

@ -2,7 +2,7 @@ import Foundation
import CoreGraphics
#if !CARTHAGE
import SWXMLHash
import SWXMLHash
#endif
///
@ -101,7 +101,7 @@ open class SVGParser {
prepareSvg(child)
}
}
fileprivate func prepareSvg(_ node: XMLIndexer) {
if let element = node.element {
if (element.name == "defs") {
@ -318,7 +318,7 @@ open class SVGParser {
return .none
}
}
fileprivate func parseGroup(_ group: XMLIndexer, groupStyle: [String: String] = [:]) -> Group? {
guard let element = group.element else {
return .none
@ -1060,11 +1060,11 @@ open class SVGParser {
if let gradientTransform = element.allAttributes["gradientTransform"]?.text {
let transform = parseTransformationAttribute(gradientTransform)
let cgTransform = RenderUtils.mapTransform(transform)
let point1 = CGPoint(x: x1, y: y1).applying(cgTransform)
x1 = point1.x.doubleValue
y1 = point1.y.doubleValue
let point2 = CGPoint(x: x2, y: y2).applying(cgTransform)
x2 = point2.x.doubleValue
y2 = point2.y.doubleValue
@ -1122,11 +1122,11 @@ open class SVGParser {
if let gradientTransform = element.allAttributes["gradientTransform"]?.text {
let transform = parseTransformationAttribute(gradientTransform)
let cgTransform = RenderUtils.mapTransform(transform)
let point1 = CGPoint(x: cx, y: cy).applying(cgTransform)
cx = point1.x.doubleValue
cy = point1.y.doubleValue
let point2 = CGPoint(x: fx, y: fy).applying(cgTransform)
fx = point2.x.doubleValue
fy = point2.y.doubleValue
@ -1316,7 +1316,7 @@ open class SVGParser {
}
private class PathDataReader {
private let input: String
private var current: UnicodeScalar?
private var previous: UnicodeScalar?
@ -1326,9 +1326,9 @@ private class PathDataReader {
self.input = input
self.iterator = input.unicodeScalars.makeIterator()
}
public func read() -> [PathSegment] {
let _ = readNext()
_ = readNext()
var segments = [PathSegment]()
while let array = readSegments() {
segments.append(contentsOf: array)
@ -1416,11 +1416,11 @@ private class PathDataReader {
current = iterator.next()
return current
}
private func readSegmentType() -> PathSegmentType? {
while(true) {
if let type = getPathSegmentType() {
let _ = readNext()
_ = readNext()
return type
}
if (readNext() == nil) {
@ -1428,7 +1428,7 @@ private class PathDataReader {
}
}
}
fileprivate func getPathSegmentType() -> PathSegmentType? {
if let ch = current {
switch(ch) {
@ -1456,7 +1456,7 @@ private class PathDataReader {
}
return nil
}
fileprivate func getArgCount(segment: PathSegmentType) -> Int {
switch(segment) {
case .H, .h, .V, .v: return 1

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
open class SVGView: MacawView {

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
internal extension CGFloat {

View File

@ -9,7 +9,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
var imagesMap = [String: MImage]()

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
///
/// MacawView is a main class used to embed Macaw scene into your Cocoa UI.
@ -168,7 +168,7 @@ open class MacawView: MView, MGestureRecognizerDelegate {
}
MGraphicsEndImageContext()
}
public final func findNodeAt(location: CGPoint) -> Node? {
guard let ctx = context.cgContext else { return .none }
return renderer?.findNodeAt(location: location, ctx: ctx)
@ -331,34 +331,34 @@ open class MacawView: MView, MGestureRecognizerDelegate {
}
// MARK: - Tap
@objc func handleLongTap(recognizer: MLongPressGestureRecognizer) {
if !self.node.shouldCheckForLongTap() {
return
}
guard let renderer = renderer else {
return
}
let location = recognizer.location(in: self)
var foundNodes = [Node]()
localContext { ctx in
guard let foundNode = renderer.findNodeAt(location: location, ctx: ctx) else {
return
}
var parent: Node? = foundNode
while parent != .none {
if parent!.shouldCheckForTap() {
foundNodes.append(parent!)
}
parent = nodesMap.parents(parent!).first
}
}
foundNodes.forEach { node in
let inverted = node.place.invert()!
let loc = location.applying(RenderUtils.mapTransform(inverted))
@ -366,7 +366,7 @@ open class MacawView: MView, MGestureRecognizerDelegate {
node.handleLongTap(event, touchBegan: recognizer.state == .began)
}
}
// MARK: - Pan
@objc func handlePan(recognizer: MPanGestureRecognizer) {

View File

@ -1,7 +1,7 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#endif
let nodesMap = NodesMap()

View File

@ -1,9 +1,9 @@
import Foundation
#if os(iOS)
import UIKit
import UIKit
#elseif os(OSX)
import AppKit
import AppKit
#endif
class ShapeLayer: CAShapeLayer {