I have Metal by Tutorials and chapter 9, navigating a 3d Scene the mouse is hooked up to rotate the scene. However, when one clicks on the window titlebar to move the window that also rotates the scene (the GameController framework seems to include the titlebar as part of the window). Is there a way to limit the triggering to just the active window view, and not moving the window as well.
Hi @charleskerr64 and welcome to the forum
I find the GameController framework a bit lacking in this area.
One solution is to add a tracking area to the window. (This is macOS only - you’d surround any macOS only commands with the necessary #if os(macOS)
test.)
Change the input controller.
- In InputController.swift, add this property to
InputController
:
var canMouseDown = false
- In
init
, change theGCMouse
pressedChangedHandler
closure to:
self.leftMouseDown = self.canMouseDown && pressed
Create a metalview
subclass
- In MetalView.swift, add this code to the bottom of the file:
class MyMTKView: MTKView {
override func mouseDown(with event: NSEvent) {
InputController.shared.canMouseDown = true
}
override func mouseUp(with event: NSEvent) {
InputController.shared.canMouseDown = false
}
}
- In MetalView.swift, in
MetalView
, change the definition ofmetalView
to beMyMTKView()
. InMetalViewRepresentable
, change the binding to beMyMTKView
.
Add the tracking area
- in MetalView.swift, in
makeNSView(context:)
, replacemetalView
with:
let trackingArea = NSTrackingArea(
rect: metalView.bounds,
options: [
.activeWhenFirstResponder,
.mouseMoved,
.enabledDuringMouseDrag
],
owner: self, userInfo: nil)
metalView.addTrackingArea(trackingArea)
return metalView
This adds a tracking area to the view.
The app recognises the mouse tracking area, and when there’s a mouse event, the app calls the overridden mouse methods. mouseDown(with:)
is only called if the event occurs inside metalView
.
You set canMouseDown
in the Input Controller, so that you can test there whether the mouse is inside the window.
There may be a better way of doing it, but there’s not too much code here.
Thanks! I finally took a tad different approach. I subclass MTKView, and add the mouseDown/mouseUp overrides.
override func mouseUp(with event: NSEvent) {
if event.buttonNumber == 0 {
InputController.shared.leftMouseDown = false
InputController.shared.removeMouseObserver()
}
}
override func mouseDown(with event: NSEvent) {
if event.buttonNumber == 0 {
InputController.shared.leftMouseDown = true
InputController.shared.addMouseObserver()
I then changed InputController init to only capture the scroll wheel:
// we are only going to monitor the scrolling wheel
center.addObserver( forName: .GCMouseDidConnect, object: nil, queue: nil) { notification in
let mouse = notification.object as? GCMouse
mouse?.mouseInput?.scroll.valueChangedHandler = { _, xValue, yValue in
self.mouseScroll.x = xValue
self.mouseScroll.y = yValue
}
}
And finally added two methods to InputController:
func addMouseObserver() {
for mouse in GCMouse.mice() {
mouse.mouseInput?.mouseMovedHandler = { _, deltaX, deltaY in
self.mouseDelta = Point(x: deltaX, y: deltaY)
}
}
}
func removeMouseObserver() {
for mouse in GCMouse.mice() {
mouse.mouseInput?.mouseMovedHandler = nil
}
}
That way I only get the mouse movement interrupts when the mouse is down.
Since I am making a utility tool (map editor), only getting the mouse when needed is ok for me. I appreciate your input, wanted to ensure I was on the correct track
Oh, I wanted to say, I really enjoy the Book. I don’t think I would have ever gotten past the “hump” on Metal without it. The style/examples has been great!
My only “negative”, is I had to buy it twice. I got it originally off Amazon, and then found out about the ability to get an ePub version direct (but had to buy it again). Luckily I use it a lot, so that isn’t the end of the world.
Again, I appreciate the quality of the book, thanks again!
Thank you for your kind words! It’s so great to hear that the book has helped.
I’m sorry you had to get it twice though. That’s annoying.
Well, the book has been great, so I can choose to ignore that fact of the double cost.
I don’t find actual books like this anymore, much less something that isn’t solely geared to IOS. It has been great, and I hope you continue! I hope you consider doing one on SceneKit (although I realize that may be on the way out), especially with working with Metal, and especially on macOS (or just don’t make it only IOS!)