2016-03-05 19:45:09 +00:00
|
|
|
//
|
2020-08-04 22:22:14 +00:00
|
|
|
// CSScanTargetView.h
|
2016-03-05 19:45:09 +00:00
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 16/07/2015.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2015 Thomas Harte. All rights reserved.
|
2016-03-05 19:45:09 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import <AppKit/AppKit.h>
|
2020-08-04 22:22:14 +00:00
|
|
|
#import <MetalKit/MetalKit.h>
|
2016-03-05 19:45:09 +00:00
|
|
|
|
2020-08-04 22:22:14 +00:00
|
|
|
@class CSScanTargetView;
|
2020-08-09 02:49:02 +00:00
|
|
|
@class CSScanTarget;
|
2016-03-05 19:45:09 +00:00
|
|
|
|
2020-08-04 22:22:14 +00:00
|
|
|
@protocol CSScanTargetViewResponderDelegate <NSObject>
|
2016-03-13 17:38:03 +00:00
|
|
|
/*!
|
2018-05-13 15:12:03 +00:00
|
|
|
Supplies a keyDown event to the delegate.
|
2016-03-13 17:38:03 +00:00
|
|
|
@param event The @c NSEvent describing the keyDown.
|
|
|
|
*/
|
2016-03-05 19:45:09 +00:00
|
|
|
- (void)keyDown:(nonnull NSEvent *)event;
|
2016-03-13 17:38:03 +00:00
|
|
|
|
|
|
|
/*!
|
2018-05-13 15:12:03 +00:00
|
|
|
Supplies a keyUp event to the delegate.
|
2016-03-13 17:38:03 +00:00
|
|
|
@param event The @c NSEvent describing the keyUp.
|
|
|
|
*/
|
2016-03-05 19:45:09 +00:00
|
|
|
- (void)keyUp:(nonnull NSEvent *)event;
|
2016-03-13 17:38:03 +00:00
|
|
|
|
|
|
|
/*!
|
2018-05-13 15:12:03 +00:00
|
|
|
Supplies a flagsChanged event to the delegate.
|
2016-03-13 17:38:03 +00:00
|
|
|
@param event The @c NSEvent describing the flagsChanged.
|
|
|
|
*/
|
2017-07-22 01:27:50 +00:00
|
|
|
- (void)flagsChanged:(nonnull NSEvent *)event;
|
2016-03-13 17:38:03 +00:00
|
|
|
|
2018-05-13 15:12:03 +00:00
|
|
|
/*!
|
|
|
|
Supplies a paste event to the delegate.
|
|
|
|
*/
|
|
|
|
- (void)paste:(nonnull id)sender;
|
|
|
|
|
2019-06-11 20:30:53 +00:00
|
|
|
@optional
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Supplies a mouse moved event to the delegate. This functions only if
|
|
|
|
shouldCaptureMouse is set to YES, in which case the view will ensure it captures
|
|
|
|
the mouse and returns only relative motion
|
|
|
|
(Cf. CGAssociateMouseAndMouseCursorPosition). It will also elide mouseDragged:
|
|
|
|
(and rightMouseDragged:, etc) and mouseMoved: events.
|
|
|
|
*/
|
|
|
|
- (void)mouseMoved:(nonnull NSEvent *)event;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Supplies a mouse button down event. This elides mouseDown, rightMouseDown and otherMouseDown.
|
|
|
|
@c shouldCaptureMouse must be set to @c YES to receive these events.
|
|
|
|
*/
|
|
|
|
- (void)mouseDown:(nonnull NSEvent *)event;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Supplies a mouse button up event. This elides mouseUp, rightMouseUp and otherMouseUp.
|
|
|
|
@c shouldCaptureMouse must be set to @c YES to receive these events.
|
|
|
|
*/
|
|
|
|
- (void)mouseUp:(nonnull NSEvent *)event;
|
|
|
|
|
2020-08-04 22:22:14 +00:00
|
|
|
/*!
|
|
|
|
Announces 'capture' of the mouse — i.e. that the view is now preventing the mouse from exiting
|
|
|
|
the window, in order to forward continuous mouse motion.
|
|
|
|
@param view The view making the announcement.
|
|
|
|
*/
|
2020-09-14 02:11:51 +00:00
|
|
|
- (void)scanTargetViewDidCaptureMouse:(nonnull CSScanTargetView *)view;
|
2020-08-04 22:22:14 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Announces that the mouse is no longer captured.
|
|
|
|
@param view The view making the announcement.
|
|
|
|
*/
|
2020-09-14 02:11:51 +00:00
|
|
|
- (void)scanTargetViewDidReleaseMouse:(nonnull CSScanTargetView *)view;
|
2020-08-04 22:22:14 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Announces that the OS mouse cursor is now being displayed again, after having been invisible.
|
|
|
|
@param view The view making the announcement.
|
|
|
|
*/
|
2020-09-14 02:11:51 +00:00
|
|
|
- (void)scanTargetViewDidShowOSMouseCursor:(nonnull CSScanTargetView *)view;
|
2020-08-04 22:22:14 +00:00
|
|
|
|
|
|
|
/*!
|
2021-07-16 21:21:25 +00:00
|
|
|
Announces that the OS mouse cursor would now be hidden; 'would' means that if this is not
|
|
|
|
a mouse capture-enabled view then it will be hidden, but otherwise it might or might not be
|
|
|
|
as per whatever is user-friendly.
|
2020-08-04 22:22:14 +00:00
|
|
|
@param view The view making the announcement.
|
|
|
|
*/
|
2021-07-16 21:21:25 +00:00
|
|
|
- (void)scanTargetViewWouldHideOSMouseCursor:(nonnull CSScanTargetView *)view;
|
2020-08-04 22:22:14 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Announces receipt of a file by drag and drop to the delegate.
|
|
|
|
@param view The view making the request.
|
|
|
|
@param URL The file URL of the received file.
|
|
|
|
*/
|
2020-09-14 02:11:51 +00:00
|
|
|
- (void)scanTargetView:(nonnull CSScanTargetView *)view didReceiveFileAtURL:(nonnull NSURL *)URL;
|
2020-08-04 22:22:14 +00:00
|
|
|
|
2016-03-05 19:45:09 +00:00
|
|
|
@end
|
|
|
|
|
2020-02-04 02:58:29 +00:00
|
|
|
/*!
|
2020-08-04 22:22:14 +00:00
|
|
|
Although I'm still on the fence about this as a design decision, CSScanTargetView is itself responsible
|
2020-02-04 02:58:29 +00:00
|
|
|
for creating and destroying a CVDisplayLink. There's a practical reason for this: you'll get real synchronisation
|
2020-08-04 22:22:14 +00:00
|
|
|
only if a link is explicitly tied to a particular display, and the CSScanTargetView therefore owns the knowledge
|
2020-02-04 02:58:29 +00:00
|
|
|
necessary to decide when to create and modify them. It doesn't currently just propagate "did change screen"-type
|
|
|
|
messages because I haven't yet found a way to track that other than polling, in which case I might as well put
|
|
|
|
that into the display link callback.
|
|
|
|
*/
|
2020-08-04 22:22:14 +00:00
|
|
|
@protocol CSScanTargetViewDisplayLinkDelegate
|
2020-02-04 02:58:29 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Informs the delegate that the display link has fired.
|
|
|
|
*/
|
2020-09-14 02:11:51 +00:00
|
|
|
- (void)scanTargetViewDisplayLinkDidFire:(nonnull CSScanTargetView *)view now:(nonnull const CVTimeStamp *)now outputTime:(nonnull const CVTimeStamp *)outputTime;
|
2020-02-04 02:58:29 +00:00
|
|
|
|
|
|
|
@end
|
|
|
|
|
2016-03-05 19:45:09 +00:00
|
|
|
/*!
|
2020-09-14 02:11:51 +00:00
|
|
|
Provides a visible scan target with a refresh-linked update timer that can forward a subset
|
2018-05-13 15:12:03 +00:00
|
|
|
of typical first-responder actions.
|
2016-03-05 19:45:09 +00:00
|
|
|
*/
|
2020-08-04 22:22:14 +00:00
|
|
|
@interface CSScanTargetView : MTKView
|
2016-03-05 19:45:09 +00:00
|
|
|
|
2020-08-04 22:22:14 +00:00
|
|
|
@property (nonatomic, weak, nullable) id <CSScanTargetViewResponderDelegate> responderDelegate;
|
|
|
|
@property (atomic, weak, nullable) id <CSScanTargetViewDisplayLinkDelegate> displayLinkDelegate;
|
2016-03-05 19:45:09 +00:00
|
|
|
|
2019-09-22 17:15:35 +00:00
|
|
|
/// Determines whether the view offers mouse capturing — i.e. if the user clicks on the view then
|
2020-08-04 22:22:14 +00:00
|
|
|
/// then the system cursor is disabled and the mouse events defined by CSScanTargetViewResponderDelegate
|
2019-09-22 17:15:35 +00:00
|
|
|
/// are forwarded, unless and until the user releases the mouse using the control+command shortcut.
|
2019-06-11 20:30:53 +00:00
|
|
|
@property (nonatomic, assign) BOOL shouldCaptureMouse;
|
|
|
|
|
2020-08-04 22:22:14 +00:00
|
|
|
/// Determines whether the CSScanTargetViewResponderDelegate of this window expects to use the command
|
2019-09-22 17:15:35 +00:00
|
|
|
/// key as though it were any other key — i.e. all command combinations should be forwarded to the delegate,
|
|
|
|
/// not being allowed to trigger regular application shortcuts such as command+q or command+h.
|
|
|
|
///
|
|
|
|
/// How the view respects this will depend on other state; if this view is one that captures the mouse then it
|
|
|
|
/// will usurp command only while the mouse is captured.
|
|
|
|
///
|
|
|
|
/// TODO: what's smart behaviour if this view doesn't capture the mouse? Probably
|
|
|
|
/// force a similar capturing behaviour?
|
|
|
|
@property (nonatomic, assign) BOOL shouldUsurpCommand;
|
|
|
|
|
2016-03-13 17:38:03 +00:00
|
|
|
/*!
|
|
|
|
Ends the timer tracking time; should be called prior to giving up the last owning reference
|
|
|
|
to ensure that any retain cycles implied by the timer are resolved.
|
|
|
|
*/
|
2016-03-05 19:45:09 +00:00
|
|
|
- (void)invalidate;
|
|
|
|
|
2020-09-14 02:11:51 +00:00
|
|
|
/*!
|
|
|
|
Ensures output begins on all pending scans.
|
|
|
|
*/
|
2020-08-16 01:24:10 +00:00
|
|
|
- (void)updateBacking;
|
2016-03-20 02:46:17 +00:00
|
|
|
|
2019-06-11 20:30:53 +00:00
|
|
|
/*!
|
|
|
|
Instructs that the mouse cursor, if currently captured, should be released.
|
|
|
|
*/
|
|
|
|
- (void)releaseMouse;
|
|
|
|
|
2020-09-14 02:30:17 +00:00
|
|
|
/*!
|
|
|
|
@returns An image of the view's current contents.
|
|
|
|
*/
|
|
|
|
- (nonnull NSBitmapImageRep *)imageRepresentation;
|
|
|
|
|
2020-08-09 02:49:02 +00:00
|
|
|
/*!
|
|
|
|
@returns The CSScanTarget being used for this display.
|
|
|
|
*/
|
|
|
|
@property(nonatomic, readonly, nonnull) CSScanTarget *scanTarget;
|
|
|
|
|
2021-05-01 01:37:41 +00:00
|
|
|
/*!
|
|
|
|
Indicates that the enclosed scan target is about to be handed off to a new owner;
|
|
|
|
exactly identical to calling scanTarget.will_change_owner().
|
|
|
|
*/
|
|
|
|
- (void)willChangeScanTargetOwner;
|
|
|
|
|
2016-03-05 19:45:09 +00:00
|
|
|
@end
|