mirror of
https://github.com/exyte/Macaw.git
synced 2024-10-26 13:01:25 +03:00
Basic mouse events
This commit is contained in:
parent
5b8783b637
commit
e385d25bca
@ -45,10 +45,71 @@ class EventsExampleController: NSViewController {
|
||||
let canvas = Shape(form: Rect(x: 0.0, y: 0.0,
|
||||
w: Double(macawView!.bounds.width),
|
||||
h: Double(macawView!.bounds.height)),
|
||||
fill: Color.clear)
|
||||
fill: Color.white)
|
||||
let objectsGroup = Group(contents:[])
|
||||
|
||||
return [canvas, objectsGroup].group()
|
||||
var startPoint = Point()
|
||||
var currentFigure: Shape?
|
||||
|
||||
canvas.onTouchPressed { event in
|
||||
guard let tool = self.selectedTool else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let loc = event.points.first?.location else {
|
||||
return
|
||||
}
|
||||
|
||||
startPoint = loc
|
||||
switch tool {
|
||||
case .ellipse:
|
||||
currentFigure = Shape(form: Ellipse(cx: startPoint.x, cy: startPoint.y, rx: 0.0, ry: 0.0))
|
||||
break
|
||||
|
||||
case .rectangle:
|
||||
currentFigure = Shape(form: Rect(x: startPoint.x, y: startPoint.y, w: 0.0, h: 0.0))
|
||||
break
|
||||
}
|
||||
|
||||
var updatedContents = objectsGroup.contents
|
||||
updatedContents.append(currentFigure!)
|
||||
|
||||
objectsGroup.contents = updatedContents
|
||||
}
|
||||
|
||||
canvas.onTouchMoved { event in
|
||||
guard let tool = self.selectedTool else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let loc = event.points.first?.location else {
|
||||
return
|
||||
}
|
||||
|
||||
let width = loc.x - startPoint.x
|
||||
let height = loc.y - startPoint.y
|
||||
|
||||
switch tool {
|
||||
case .ellipse:
|
||||
|
||||
currentFigure?.form = Ellipse(
|
||||
cx: startPoint.x + width / 2.0,
|
||||
cy: startPoint.y + height / 2.0,
|
||||
rx: width / 2.0,
|
||||
ry: height / 2.0)
|
||||
break
|
||||
|
||||
case .rectangle:
|
||||
currentFigure?.form = Rect(x: startPoint.x, y: startPoint.y, w: width, h: height)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return [
|
||||
canvas,
|
||||
objectsGroup
|
||||
].group()
|
||||
}
|
||||
|
||||
private func createTools() -> Node {
|
||||
|
@ -69,6 +69,8 @@ class EventsExampleController: UIViewController {
|
||||
return
|
||||
}
|
||||
|
||||
print("canvas pressed:\(loc.x) \(loc.y)")
|
||||
|
||||
startPoint = loc
|
||||
switch tool {
|
||||
case .ellipse:
|
||||
@ -87,6 +89,7 @@ class EventsExampleController: UIViewController {
|
||||
}
|
||||
|
||||
canvas.onTouchMoved { event in
|
||||
|
||||
guard let tool = self.selectedTool else {
|
||||
return
|
||||
}
|
||||
@ -95,6 +98,8 @@ class EventsExampleController: UIViewController {
|
||||
return
|
||||
}
|
||||
|
||||
print("canvas moving \(loc.x) \(loc.y)")
|
||||
|
||||
let width = loc.x - startPoint.x
|
||||
let height = loc.y - startPoint.y
|
||||
|
||||
|
@ -11,7 +11,7 @@ EXTERNAL SOURCES:
|
||||
:path: "../"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Macaw: ceb6b88ed35e027b9b40804fed254b9e0e700c81
|
||||
Macaw: 5bd466e34d3602084f43486abbc31fc4a8060c74
|
||||
SWXMLHash: 701f7d07c032089b9ff34e0352bd4fed1a24652a
|
||||
|
||||
PODFILE CHECKSUM: cf6c204dbe194da8e03fcb9ffd9c99d086057155
|
||||
|
@ -11,7 +11,7 @@ import Foundation
|
||||
#if os(iOS)
|
||||
import UIKit
|
||||
|
||||
open class MView: UIView {
|
||||
open class MView: UIView, Touchable {
|
||||
var mLayer: CALayer? {
|
||||
return self.layer
|
||||
}
|
||||
@ -25,35 +25,71 @@ import Foundation
|
||||
}
|
||||
|
||||
open override func touchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
self.mTouchesBegan(touches, with: event)
|
||||
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?) {
|
||||
self.mTouchesMoved(touches, with: event)
|
||||
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?) {
|
||||
self.mTouchesEnded(touches, with: event)
|
||||
}
|
||||
|
||||
open override func touchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
self.mTouchesCancelled(touches, with: event)
|
||||
}
|
||||
|
||||
open func mTouchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
super.touchesBegan(touches, with: event)
|
||||
}
|
||||
|
||||
open func mTouchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
super.touchesMoved(touches, with: event)
|
||||
}
|
||||
|
||||
open func mTouchesEnded(_ 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)
|
||||
}
|
||||
|
||||
open func mTouchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
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]) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ import Foundation
|
||||
case bottomRight
|
||||
}
|
||||
|
||||
open class MView: NSView {
|
||||
open class MView: NSView, Touchable {
|
||||
public override init(frame frameRect: NSRect) {
|
||||
super.init(frame: frameRect)
|
||||
|
||||
@ -38,6 +38,7 @@ import Foundation
|
||||
super.init(coder: coder)
|
||||
|
||||
self.wantsLayer = true
|
||||
setupMouse()
|
||||
}
|
||||
|
||||
open override var isFlipped: Bool {
|
||||
@ -80,36 +81,177 @@ import Foundation
|
||||
super.resizeSubviews(withOldSize: self.bounds.size)
|
||||
}
|
||||
|
||||
// MARK: - Touch pad
|
||||
open override func touchesBegan(with event: NSEvent) {
|
||||
self.mTouchesBegan(event.touches(matching: .any, in: self), with: event)
|
||||
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) {
|
||||
self.mTouchesEnded(event.touches(matching: .any, in: self), with: event)
|
||||
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) {
|
||||
self.mTouchesMoved(event.touches(matching: .any, in: self), with: event)
|
||||
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) {
|
||||
self.mTouchesCancelled(event.touches(matching: .any, in: self), with: event)
|
||||
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)
|
||||
}
|
||||
|
||||
open func mTouchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
super.touchesBegan(with: event!)
|
||||
mTouchesCancelled(touchPoints)
|
||||
}
|
||||
|
||||
open func mTouchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
super.touchesMoved(with: event!)
|
||||
// MARK: - Mouse
|
||||
private func setupMouse() {
|
||||
subscribeForMouseDown()
|
||||
subscribeForMouseUp()
|
||||
subscribeForMouseDragged()
|
||||
}
|
||||
|
||||
open func mTouchesEnded(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
super.touchesEnded(with: event!)
|
||||
private func subscribeForMouseDown() {
|
||||
NSEvent.addLocalMonitorForEvents(matching: .leftMouseDown, handler: { [weak self] event -> NSEvent? in
|
||||
guard let weakSelf = self else {
|
||||
return event
|
||||
}
|
||||
|
||||
open func mTouchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
super.touchesCancelled(with: event!)
|
||||
// Touch pad
|
||||
guard event.subtype == .touch else {
|
||||
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
|
||||
let location = touch.location(in: weakSelf)
|
||||
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
|
||||
|
||||
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
|
||||
}
|
||||
|
||||
weakSelf.mTouchesBegan(touchPoints)
|
||||
return event
|
||||
}
|
||||
|
||||
// Mouse
|
||||
let location = weakSelf.convert(event.locationInWindow, to: .none)
|
||||
let id = 0
|
||||
let touchPoint = MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
|
||||
|
||||
|
||||
weakSelf.mTouchesBegan([touchPoint])
|
||||
|
||||
return event
|
||||
})
|
||||
}
|
||||
|
||||
private func subscribeForMouseUp() {
|
||||
NSEvent.addLocalMonitorForEvents(matching: .leftMouseUp, handler: { [weak self] event -> NSEvent? in
|
||||
guard let weakSelf = self else {
|
||||
return event
|
||||
}
|
||||
|
||||
// Touch pad
|
||||
guard event.subtype == .touch else {
|
||||
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
|
||||
let location = touch.location(in: weakSelf)
|
||||
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
|
||||
|
||||
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
|
||||
}
|
||||
|
||||
weakSelf.mTouchesEnded(touchPoints)
|
||||
return event
|
||||
}
|
||||
|
||||
// Mouse
|
||||
let location = weakSelf.convert(event.locationInWindow, to: .none)
|
||||
let id = 0
|
||||
|
||||
let touchPoint = MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
|
||||
|
||||
|
||||
weakSelf.mTouchesEnded([touchPoint])
|
||||
|
||||
return event
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private func subscribeForMouseDragged() {
|
||||
NSEvent.addLocalMonitorForEvents(matching: .leftMouseDragged, handler: { [weak self] event -> NSEvent? in
|
||||
guard let weakSelf = self else {
|
||||
return event
|
||||
}
|
||||
|
||||
// Touch pad
|
||||
guard event.subtype == .touch else {
|
||||
let touchPoints = event.touches(matching: .any, in: self).map { touch -> MTouchEvent in
|
||||
let location = touch.location(in: weakSelf)
|
||||
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
|
||||
|
||||
return MTouchEvent(x: Double(location.x), y: Double(location.y), id: id)
|
||||
}
|
||||
|
||||
weakSelf.mTouchesMoved(touchPoints)
|
||||
return event
|
||||
}
|
||||
|
||||
// Mouse
|
||||
let location = weakSelf.convert(event.locationInWindow, to: .none)
|
||||
let id = 0
|
||||
|
||||
let touchPoint = MTouchEvent(x: Double(location.x), y: Double(location.y), id: 0)
|
||||
|
||||
|
||||
weakSelf.mTouchesMoved([touchPoint])
|
||||
|
||||
return event
|
||||
})
|
||||
}
|
||||
|
||||
// MARK: - Touchable
|
||||
func mTouchesBegan(_ touches: [MTouchEvent]) {
|
||||
|
||||
}
|
||||
|
||||
func mTouchesMoved(_ touches: [MTouchEvent]) {
|
||||
|
||||
}
|
||||
|
||||
func mTouchesEnded(_ touches: [MTouchEvent]) {
|
||||
|
||||
}
|
||||
|
||||
func mTouchesCancelled(_ touches: [MTouchEvent]) {
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -56,8 +56,8 @@ open class MacawView: MView, MGestureRecognizerDelegate {
|
||||
animationProducer.addStoredAnimations(node)
|
||||
}
|
||||
|
||||
var touchesMap = [MTouch: [Node]]()
|
||||
var touchesOfNode = [Node: [MTouch]]()
|
||||
var touchesMap = [MTouchEvent: [Node]]()
|
||||
var touchesOfNode = [Node: [MTouchEvent]]()
|
||||
var recognizersMap = [MGestureRecognizer: [Node]]()
|
||||
|
||||
var context: RenderContext!
|
||||
@ -240,7 +240,7 @@ open class MacawView: MView, MGestureRecognizerDelegate {
|
||||
|
||||
// MARK: - Touches
|
||||
|
||||
open override func mTouchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
override func mTouchesBegan(_ touches: [MTouchEvent]) {
|
||||
|
||||
if !self.node.shouldCheckForPressed() &&
|
||||
!self.node.shouldCheckForMoved() &&
|
||||
@ -253,7 +253,7 @@ open class MacawView: MView, MGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
for touch in touches {
|
||||
let location = touch.location(in: self)
|
||||
let location = CGPoint(x: touch.x, y: touch.y)
|
||||
NSLog("\(location)")
|
||||
var foundNode: Node? = .none
|
||||
localContext { ctx in
|
||||
@ -276,7 +276,7 @@ open class MacawView: MView, MGestureRecognizerDelegate {
|
||||
while parent != .none {
|
||||
let currentNode = parent!
|
||||
if touchesOfNode[currentNode] == nil {
|
||||
touchesOfNode[currentNode] = [MTouch]()
|
||||
touchesOfNode[currentNode] = [MTouchEvent]()
|
||||
}
|
||||
|
||||
touchesMap[touch]?.append(currentNode)
|
||||
@ -289,7 +289,7 @@ open class MacawView: MView, MGestureRecognizerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
open override func mTouchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
override func mTouchesMoved(_ touches: [MTouchEvent]) {
|
||||
if !self.node.shouldCheckForMoved() {
|
||||
return
|
||||
}
|
||||
@ -299,17 +299,18 @@ open class MacawView: MView, MGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
touchesOfNode.keys.forEach { currentNode in
|
||||
guard let touches = touchesOfNode[currentNode] else {
|
||||
guard let initialTouches = touchesOfNode[currentNode] else {
|
||||
return
|
||||
}
|
||||
|
||||
var points = [TouchPoint]()
|
||||
for touch in touches {
|
||||
let location = touch.location(in: self)
|
||||
for initialTouch in initialTouches {
|
||||
let currentIndex = touches.index(of: initialTouch)!
|
||||
let currentTouch = touches[currentIndex]
|
||||
let location = CGPoint(x: currentTouch.x, y: currentTouch.y)
|
||||
let inverted = currentNode.place.invert()!
|
||||
let loc = location.applying(RenderUtils.mapTransform(inverted))
|
||||
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
|
||||
let point = TouchPoint(id: id, location: Point(x: Double(loc.x), y: Double(loc.y)))
|
||||
let point = TouchPoint(id: currentTouch.id, location: Point(x: Double(loc.x), y: Double(loc.y)))
|
||||
points.append(point)
|
||||
}
|
||||
|
||||
@ -318,25 +319,26 @@ open class MacawView: MView, MGestureRecognizerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
open override func mTouchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
touchesEnded(touches: touches, event: event)
|
||||
|
||||
override func mTouchesCancelled(_ touches: [MTouchEvent]) {
|
||||
touchesEnded(touches: touches)
|
||||
}
|
||||
|
||||
open override func mTouchesEnded(_ touches: Set<MTouch>, with event: MEvent?) {
|
||||
touchesEnded(touches: touches, event: event)
|
||||
override func mTouchesEnded(_ touches: [MTouchEvent]) {
|
||||
touchesEnded(touches: touches)
|
||||
}
|
||||
|
||||
private func touchesEnded(touches: Set<MTouch>, event: MEvent?) {
|
||||
private func touchesEnded(touches: [MTouchEvent]) {
|
||||
guard let _ = renderer else {
|
||||
return
|
||||
}
|
||||
|
||||
for touch in touches {
|
||||
let location = touch.location(in: self)
|
||||
|
||||
touchesMap[touch]?.forEach { node in
|
||||
|
||||
let inverted = node.place.invert()!
|
||||
let location = CGPoint(x: touch.x, y: touch.y)
|
||||
let loc = location.applying(RenderUtils.mapTransform(inverted))
|
||||
let id = Int(bitPattern: Unmanaged.passUnretained(touch).toOpaque())
|
||||
let point = TouchPoint(id: id, location: Point(x: Double(loc.x), y: Double(loc.y)))
|
||||
|
26
Source/views/Touchable.swift
Normal file
26
Source/views/Touchable.swift
Normal file
@ -0,0 +1,26 @@
|
||||
class MTouchEvent: Hashable {
|
||||
let id: Int
|
||||
let x: Double
|
||||
let y: Double
|
||||
|
||||
init(x: Double, y: Double, id: Int) {
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.id = id
|
||||
}
|
||||
|
||||
public var hashValue: Int {
|
||||
return id.hashValue
|
||||
}
|
||||
|
||||
public static func ==(lhs: MTouchEvent, rhs: MTouchEvent) -> Bool {
|
||||
return lhs.id == rhs.id
|
||||
}
|
||||
}
|
||||
|
||||
protocol Touchable {
|
||||
func mTouchesBegan(_ touches: [MTouchEvent])
|
||||
func mTouchesMoved(_ touches: [MTouchEvent])
|
||||
func mTouchesEnded(_ touches: [MTouchEvent])
|
||||
func mTouchesCancelled(_ touches: [MTouchEvent])
|
||||
}
|
Loading…
Reference in New Issue
Block a user