mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-21 18:37:11 +00:00
Require mouseover near the volume/controls to activate.
This commit is contained in:
parent
e19dc1f067
commit
f8c9aa8e6c
@ -111,6 +111,7 @@ class MachineDocument:
|
||||
volumeSlider.floatValue = pow(2.0, userDefaultsVolume())
|
||||
|
||||
volumeView.layer!.cornerRadius = 5.0
|
||||
scanTargetView.responderDelegate = self
|
||||
}
|
||||
|
||||
private var missingROMs: String = ""
|
||||
@ -227,7 +228,6 @@ class MachineDocument:
|
||||
setupActivityDisplay()
|
||||
|
||||
machine.delegate = self
|
||||
scanTargetView.responderDelegate = self
|
||||
|
||||
// If this machine has a mouse, enable mouse capture; also indicate whether usurption
|
||||
// of the command key is desired.
|
||||
@ -782,6 +782,10 @@ class MachineDocument:
|
||||
|
||||
private var optionsFader: ViewFader! = nil
|
||||
|
||||
internal func scanTargetView(_ view: CSScanTargetView, shouldTrackMousovers subview: NSView) -> Bool {
|
||||
return subview == self.volumeView || subview == self.optionsView
|
||||
}
|
||||
|
||||
internal func scanTargetViewDidShowOSMouseCursor(_ view: CSScanTargetView) {
|
||||
// The OS mouse cursor became visible, so show the volume controls.
|
||||
optionsFader.animateIn()
|
||||
|
@ -94,6 +94,13 @@
|
||||
*/
|
||||
- (void)scanTargetView:(nonnull CSScanTargetView *)view didReceiveFileAtURL:(nonnull NSURL *)URL;
|
||||
|
||||
/*!
|
||||
Asks the receiver whether @c view should be included in the set of subviews that generate
|
||||
@c scanTargetViewDidShowOSMouseCursor and subsequent actions.
|
||||
*/
|
||||
- (BOOL)scanTargetView:(nonnull CSScanTargetView *)view shouldTrackMousovers:(nonnull NSView *)view;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
|
@ -24,7 +24,8 @@ static const NSTimeInterval quickMouseHideInterval = 0.1;
|
||||
CVDisplayLinkRef _displayLink;
|
||||
NSNumber *_currentScreenNumber;
|
||||
|
||||
NSTrackingArea *_mouseTrackingArea;
|
||||
NSTrackingArea *_windowTrackingArea;
|
||||
NSTrackingArea *_subviewTrackingArea;
|
||||
NSTimer *_mouseHideTimer;
|
||||
BOOL _mouseIsCaptured;
|
||||
|
||||
@ -222,21 +223,67 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
|
||||
|
||||
- (void)setShouldCaptureMouse:(BOOL)shouldCaptureMouse {
|
||||
_shouldCaptureMouse = shouldCaptureMouse;
|
||||
|
||||
if(_windowTrackingArea) {
|
||||
[self removeTrackingArea:_windowTrackingArea];
|
||||
}
|
||||
_windowTrackingArea =
|
||||
[[NSTrackingArea alloc]
|
||||
initWithRect:self.bounds
|
||||
options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveWhenFirstResponder
|
||||
owner:self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:_windowTrackingArea];
|
||||
}
|
||||
|
||||
- (void)recalculateSubviewTrackingAreas {
|
||||
if(_subviewTrackingArea) {
|
||||
[self removeTrackingArea:_subviewTrackingArea];
|
||||
}
|
||||
|
||||
// Use the union of rects of interesting subviews as the tracking area.
|
||||
const NSRect emptySentinel = NSMakeRect(-1, -1, -1, -1);
|
||||
NSRect trackingRect = emptySentinel;
|
||||
for(NSView *const subview in self.subviews) {
|
||||
if(
|
||||
[self.responderDelegate respondsToSelector:@selector(scanTargetView:shouldTrackMousovers:)] &&
|
||||
![self.responderDelegate scanTargetView:self shouldTrackMousovers:subview]
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(NSEqualRects(trackingRect, emptySentinel)) {
|
||||
trackingRect = subview.frame;
|
||||
} else {
|
||||
trackingRect = NSUnionRect(subview.frame, trackingRect);
|
||||
}
|
||||
}
|
||||
|
||||
if(NSEqualRects(trackingRect, emptySentinel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_subviewTrackingArea =
|
||||
[[NSTrackingArea alloc]
|
||||
initWithRect:trackingRect
|
||||
options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveWhenFirstResponder
|
||||
owner:self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:_subviewTrackingArea];
|
||||
}
|
||||
|
||||
- (void)updateTrackingAreas {
|
||||
[super updateTrackingAreas];
|
||||
[self recalculateSubviewTrackingAreas];
|
||||
}
|
||||
|
||||
if(_mouseTrackingArea) {
|
||||
[self removeTrackingArea:_mouseTrackingArea];
|
||||
}
|
||||
_mouseTrackingArea =
|
||||
[[NSTrackingArea alloc]
|
||||
initWithRect:self.bounds
|
||||
options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveWhenFirstResponder
|
||||
owner:self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:_mouseTrackingArea];
|
||||
- (void)didAddSubview:(NSView *)subview {
|
||||
[self recalculateSubviewTrackingAreas];
|
||||
}
|
||||
|
||||
- (void)layout {
|
||||
[super layout];
|
||||
[self recalculateSubviewTrackingAreas];
|
||||
}
|
||||
|
||||
- (void)scheduleMouseHideAfter:(NSTimeInterval)interval {
|
||||
@ -255,8 +302,12 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
|
||||
- (void)mouseEntered:(NSEvent *)event {
|
||||
[super mouseEntered:event];
|
||||
|
||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
||||
[self scheduleMouseHideAfter:standardMouseHideInterval];
|
||||
if(event.trackingArea == _windowTrackingArea) {
|
||||
[self scheduleMouseHideAfter:standardMouseHideInterval];
|
||||
}
|
||||
if(event.trackingArea == _subviewTrackingArea && !_mouseIsCaptured) {
|
||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)event {
|
||||
@ -272,7 +323,6 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
[NSCursor unhide];
|
||||
[self.responderDelegate scanTargetViewDidReleaseMouse:self];
|
||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
||||
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = nil;
|
||||
}
|
||||
}
|
||||
@ -284,7 +334,13 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
|
||||
// Mouse capture is off, so don't play games with the cursor, just schedule it to
|
||||
// hide in the near future.
|
||||
[self scheduleMouseHideAfter:standardMouseHideInterval];
|
||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
||||
|
||||
if(
|
||||
_subviewTrackingArea &&
|
||||
NSPointInRect([self convertPoint:event.locationInWindow fromView:nil], _subviewTrackingArea.rect)
|
||||
) {
|
||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
||||
}
|
||||
} else {
|
||||
// Mouse capture is on, so move the cursor back to the middle of the window, and
|
||||
// forward the deltas to the listener.
|
||||
|
Loading…
x
Reference in New Issue
Block a user