mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-07 23:25:00 +00:00
Require mouseover near the volume/controls to activate.
This commit is contained in:
@@ -111,6 +111,7 @@ class MachineDocument:
|
|||||||
volumeSlider.floatValue = pow(2.0, userDefaultsVolume())
|
volumeSlider.floatValue = pow(2.0, userDefaultsVolume())
|
||||||
|
|
||||||
volumeView.layer!.cornerRadius = 5.0
|
volumeView.layer!.cornerRadius = 5.0
|
||||||
|
scanTargetView.responderDelegate = self
|
||||||
}
|
}
|
||||||
|
|
||||||
private var missingROMs: String = ""
|
private var missingROMs: String = ""
|
||||||
@@ -227,7 +228,6 @@ class MachineDocument:
|
|||||||
setupActivityDisplay()
|
setupActivityDisplay()
|
||||||
|
|
||||||
machine.delegate = self
|
machine.delegate = self
|
||||||
scanTargetView.responderDelegate = self
|
|
||||||
|
|
||||||
// If this machine has a mouse, enable mouse capture; also indicate whether usurption
|
// If this machine has a mouse, enable mouse capture; also indicate whether usurption
|
||||||
// of the command key is desired.
|
// of the command key is desired.
|
||||||
@@ -782,6 +782,10 @@ class MachineDocument:
|
|||||||
|
|
||||||
private var optionsFader: ViewFader! = nil
|
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) {
|
internal func scanTargetViewDidShowOSMouseCursor(_ view: CSScanTargetView) {
|
||||||
// The OS mouse cursor became visible, so show the volume controls.
|
// The OS mouse cursor became visible, so show the volume controls.
|
||||||
optionsFader.animateIn()
|
optionsFader.animateIn()
|
||||||
|
@@ -94,6 +94,13 @@
|
|||||||
*/
|
*/
|
||||||
- (void)scanTargetView:(nonnull CSScanTargetView *)view didReceiveFileAtURL:(nonnull NSURL *)URL;
|
- (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
|
@end
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -24,7 +24,8 @@ static const NSTimeInterval quickMouseHideInterval = 0.1;
|
|||||||
CVDisplayLinkRef _displayLink;
|
CVDisplayLinkRef _displayLink;
|
||||||
NSNumber *_currentScreenNumber;
|
NSNumber *_currentScreenNumber;
|
||||||
|
|
||||||
NSTrackingArea *_mouseTrackingArea;
|
NSTrackingArea *_windowTrackingArea;
|
||||||
|
NSTrackingArea *_subviewTrackingArea;
|
||||||
NSTimer *_mouseHideTimer;
|
NSTimer *_mouseHideTimer;
|
||||||
BOOL _mouseIsCaptured;
|
BOOL _mouseIsCaptured;
|
||||||
|
|
||||||
@@ -222,21 +223,67 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
|
|||||||
|
|
||||||
- (void)setShouldCaptureMouse:(BOOL)shouldCaptureMouse {
|
- (void)setShouldCaptureMouse:(BOOL)shouldCaptureMouse {
|
||||||
_shouldCaptureMouse = 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 {
|
- (void)updateTrackingAreas {
|
||||||
[super updateTrackingAreas];
|
[super updateTrackingAreas];
|
||||||
|
[self recalculateSubviewTrackingAreas];
|
||||||
|
}
|
||||||
|
|
||||||
if(_mouseTrackingArea) {
|
- (void)didAddSubview:(NSView *)subview {
|
||||||
[self removeTrackingArea:_mouseTrackingArea];
|
[self recalculateSubviewTrackingAreas];
|
||||||
}
|
}
|
||||||
_mouseTrackingArea =
|
|
||||||
[[NSTrackingArea alloc]
|
- (void)layout {
|
||||||
initWithRect:self.bounds
|
[super layout];
|
||||||
options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveWhenFirstResponder
|
[self recalculateSubviewTrackingAreas];
|
||||||
owner:self
|
|
||||||
userInfo:nil];
|
|
||||||
[self addTrackingArea:_mouseTrackingArea];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scheduleMouseHideAfter:(NSTimeInterval)interval {
|
- (void)scheduleMouseHideAfter:(NSTimeInterval)interval {
|
||||||
@@ -255,8 +302,12 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
|
|||||||
- (void)mouseEntered:(NSEvent *)event {
|
- (void)mouseEntered:(NSEvent *)event {
|
||||||
[super mouseEntered:event];
|
[super mouseEntered:event];
|
||||||
|
|
||||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
if(event.trackingArea == _windowTrackingArea) {
|
||||||
[self scheduleMouseHideAfter:standardMouseHideInterval];
|
[self scheduleMouseHideAfter:standardMouseHideInterval];
|
||||||
|
}
|
||||||
|
if(event.trackingArea == _subviewTrackingArea && !_mouseIsCaptured) {
|
||||||
|
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseExited:(NSEvent *)event {
|
- (void)mouseExited:(NSEvent *)event {
|
||||||
@@ -272,7 +323,6 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
|
|||||||
CGAssociateMouseAndMouseCursorPosition(true);
|
CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
[NSCursor unhide];
|
[NSCursor unhide];
|
||||||
[self.responderDelegate scanTargetViewDidReleaseMouse:self];
|
[self.responderDelegate scanTargetViewDidReleaseMouse:self];
|
||||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
|
||||||
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = nil;
|
((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
|
// Mouse capture is off, so don't play games with the cursor, just schedule it to
|
||||||
// hide in the near future.
|
// hide in the near future.
|
||||||
[self scheduleMouseHideAfter:standardMouseHideInterval];
|
[self scheduleMouseHideAfter:standardMouseHideInterval];
|
||||||
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
|
||||||
|
if(
|
||||||
|
_subviewTrackingArea &&
|
||||||
|
NSPointInRect([self convertPoint:event.locationInWindow fromView:nil], _subviewTrackingArea.rect)
|
||||||
|
) {
|
||||||
|
[self.responderDelegate scanTargetViewDidShowOSMouseCursor:self];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Mouse capture is on, so move the cursor back to the middle of the window, and
|
// Mouse capture is on, so move the cursor back to the middle of the window, and
|
||||||
// forward the deltas to the listener.
|
// forward the deltas to the listener.
|
||||||
|
Reference in New Issue
Block a user