1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-08-16 08:30:33 +03:00

Basic mouse events

This commit is contained in:
Viktor Sukochev 2017-08-23 12:29:45 +07:00
parent 5b8783b637
commit e385d25bca
7 changed files with 380 additions and 108 deletions

View File

@ -41,15 +41,76 @@ class EventsExampleController: NSViewController {
return panelGroup
}
private func createCanvas() -> Node {
let canvas = Shape(form: Rect(x: 0.0, y: 0.0,
w: Double(macawView!.bounds.width),
h: Double(macawView!.bounds.height)),
fill: Color.clear)
let objectsGroup = Group(contents:[])
return [canvas, objectsGroup].group()
}
private func createCanvas() -> Node {
let canvas = Shape(form: Rect(x: 0.0, y: 0.0,
w: Double(macawView!.bounds.width),
h: Double(macawView!.bounds.height)),
fill: Color.white)
let objectsGroup = Group(contents:[])
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 {
let ellipseTool = Shape(form: Ellipse(cx: 50.0, cy: 50.0, rx: 25, ry: 15),

View File

@ -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

View File

@ -11,7 +11,7 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
Macaw: ceb6b88ed35e027b9b40804fed254b9e0e700c81
Macaw: 5bd466e34d3602084f43486abbc31fc4a8060c74
SWXMLHash: 701f7d07c032089b9ff34e0352bd4fed1a24652a
PODFILE CHECKSUM: cf6c204dbe194da8e03fcb9ffd9c99d086057155

View File

@ -9,53 +9,89 @@
import Foundation
#if os(iOS)
import UIKit
open class MView: UIView {
var mLayer: CALayer? {
return self.layer
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]) {
}
}
var mGestureRecognizers: [MGestureRecognizer]? {
return self.gestureRecognizers
}
func removeGestureRecognizers() {
self.gestureRecognizers?.removeAll()
}
open override func touchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
self.mTouchesBegan(touches, with: event)
}
open override func touchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
self.mTouchesMoved(touches, with: event)
}
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)
}
open func mTouchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesCancelled(touches, with: event)
}
}
#endif

View File

@ -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)
}
mTouchesCancelled(touchPoints)
}
open func mTouchesBegan(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesBegan(with: event!)
// MARK: - Mouse
private func setupMouse() {
subscribeForMouseDown()
subscribeForMouseUp()
subscribeForMouseDragged()
}
open func mTouchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesMoved(with: event!)
private func subscribeForMouseDown() {
NSEvent.addLocalMonitorForEvents(matching: .leftMouseDown, 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.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
})
}
open func mTouchesEnded(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesEnded(with: 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
})
}
open func mTouchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
super.touchesCancelled(with: 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

View File

@ -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,54 +289,56 @@ open class MacawView: MView, MGestureRecognizerDelegate {
}
}
open override func mTouchesMoved(_ touches: Set<MTouch>, with event: MEvent?) {
if !self.node.shouldCheckForMoved() {
return
}
guard let _ = renderer else {
return
}
touchesOfNode.keys.forEach { currentNode in
guard let touches = touchesOfNode[currentNode] else {
return
}
var points = [TouchPoint]()
for touch in touches {
let location = touch.location(in: self)
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)))
points.append(point)
}
let touchEvent = TouchEvent(node: currentNode, points: points)
currentNode.handleTouchMoved(touchEvent)
override func mTouchesMoved(_ touches: [MTouchEvent]) {
if !self.node.shouldCheckForMoved() {
return
}
guard let _ = renderer else {
return
}
touchesOfNode.keys.forEach { currentNode in
guard let initialTouches = touchesOfNode[currentNode] else {
return
}
var points = [TouchPoint]()
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 point = TouchPoint(id: currentTouch.id, location: Point(x: Double(loc.x), y: Double(loc.y)))
points.append(point)
}
let touchEvent = TouchEvent(node: currentNode, points: points)
currentNode.handleTouchMoved(touchEvent)
}
}
override func mTouchesCancelled(_ touches: [MTouchEvent]) {
touchesEnded(touches: touches)
}
open override func mTouchesCancelled(_ touches: Set<MTouch>, with event: MEvent?) {
touchesEnded(touches: touches, event: event)
override func mTouchesEnded(_ touches: [MTouchEvent]) {
touchesEnded(touches: touches)
}
open override func mTouchesEnded(_ touches: Set<MTouch>, with event: MEvent?) {
touchesEnded(touches: touches, event: event)
}
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)))

View 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])
}