|
@@ -1,433 +0,0 @@
|
|
|
-//
|
|
|
-// KMDrawView.m
|
|
|
-// PDF Reader
|
|
|
-//
|
|
|
-// Created by lxy on 2023/1/10.
|
|
|
-//
|
|
|
-
|
|
|
-#import "KMDrawView.h"
|
|
|
-
|
|
|
-static NSInteger _index;
|
|
|
-static CGPoint _points[5];
|
|
|
-
|
|
|
-@interface KMDrawView ()
|
|
|
-
|
|
|
-@property (nonatomic,assign) BOOL cursorIsHidden;
|
|
|
-@property (nonatomic,assign) BOOL mouseIsInView;
|
|
|
-
|
|
|
-@property (nonatomic,retain) NSTouch *activeTouch;
|
|
|
-
|
|
|
-@property (nonatomic,retain) NSBezierPath *bezierPath;
|
|
|
-
|
|
|
-@end
|
|
|
-
|
|
|
-@implementation KMDrawView
|
|
|
-
|
|
|
-- (void)dealloc
|
|
|
-{
|
|
|
- _delegate = nil;
|
|
|
-}
|
|
|
-
|
|
|
-- (id)initWithFrame:(NSRect)frameRect
|
|
|
-{
|
|
|
- if (self = [super initWithFrame:frameRect]) {
|
|
|
- self.drawImage = [[NSImage alloc] initWithSize:self.frame.size];
|
|
|
- self.drawColor = [NSColor colorWithDeviceRed:0 green:0 blue:0 alpha:1];
|
|
|
- self.strokeRadius = 0.3;
|
|
|
-
|
|
|
- _bezierPath = [[NSBezierPath alloc] init];
|
|
|
-
|
|
|
- self.wantsLayer = YES;
|
|
|
- self.layer.borderWidth = 1.0;
|
|
|
- self.layer.borderColor =[NSColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.05].CGColor;
|
|
|
-
|
|
|
- }
|
|
|
- return self;
|
|
|
-}
|
|
|
-
|
|
|
-- (NSBezierPath *)drawBezierPath {
|
|
|
- _drawBezierPath = _bezierPath;
|
|
|
-
|
|
|
- CGRect rect = self.bezierPath.bounds;
|
|
|
- NSAffineTransform *transform = [NSAffineTransform transform];
|
|
|
- [transform translateXBy:- rect.origin.x + +self.bezierPath.lineWidth/2.0 yBy:-rect.origin.y + self.bezierPath.lineWidth/2.0];
|
|
|
- [_drawBezierPath transformUsingAffineTransform:transform];
|
|
|
-
|
|
|
- return _drawBezierPath;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- ** - (BOOL) acceptsFirstResponder
|
|
|
- **
|
|
|
- ** Make sure the view will receive
|
|
|
- ** events.
|
|
|
- **
|
|
|
- ** Input: none
|
|
|
- **
|
|
|
- ** Output: YES to accept, NO to reject
|
|
|
- */
|
|
|
-- (BOOL)acceptsFirstResponder
|
|
|
-{
|
|
|
- return YES;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)setIsAcceptsTouch:(BOOL)isAcceptsTouch
|
|
|
-{
|
|
|
- _isAcceptsTouch = isAcceptsTouch;
|
|
|
-
|
|
|
- // Accept trackpad events
|
|
|
- [self setAcceptsTouchEvents:isAcceptsTouch];
|
|
|
-
|
|
|
- size_t screenHeight = CGDisplayPixelsHigh(CGMainDisplayID());
|
|
|
- NSRect frameToWindow = [self convertRect:self.bounds toView:nil];
|
|
|
- NSRect frameToScreen = [self.window convertRectToScreen:frameToWindow];
|
|
|
- if (isAcceptsTouch) {
|
|
|
- // If the mouse cursor is not already hidden,
|
|
|
- if (!self.cursorIsHidden) {
|
|
|
- frameToScreen.origin.x = frameToScreen.origin.x+5;
|
|
|
- frameToScreen.origin.y = screenHeight-frameToScreen.origin.y-5;
|
|
|
- CGWarpMouseCursorPosition(frameToScreen.origin);
|
|
|
-
|
|
|
- // Detach the mouse cursor from the mouse
|
|
|
- // hardware so that moving the mouse (or a
|
|
|
- // single finger) will not move the cursor
|
|
|
- CGAssociateMouseAndMouseCursorPosition(false);
|
|
|
-
|
|
|
- // Hide the mouse cursor
|
|
|
- [NSCursor hide];
|
|
|
-
|
|
|
- // Remember that we detached and hid the
|
|
|
- // mouse cursor
|
|
|
- self.cursorIsHidden = YES;
|
|
|
- }
|
|
|
- } else {
|
|
|
- frameToScreen.origin.y = screenHeight-frameToScreen.origin.y;
|
|
|
- CGWarpMouseCursorPosition(frameToScreen.origin);
|
|
|
-
|
|
|
- // Attach the mouse cursor to the mouse
|
|
|
- // hardware so that moving the mouse (or a
|
|
|
- // single finger) will move the cursor
|
|
|
- CGAssociateMouseAndMouseCursorPosition(true);
|
|
|
-
|
|
|
- // Show the mouse cursor
|
|
|
- [NSCursor unhide];
|
|
|
-
|
|
|
- // Remember that we attached and unhid the
|
|
|
- // mouse cursor so that the next touch that
|
|
|
- // begins will detach and hide it
|
|
|
- self.cursorIsHidden = NO;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)clearImage
|
|
|
-{
|
|
|
- self.drawImage = nil;
|
|
|
- [self.bezierPath removeAllPoints];
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
- if (self.touchEndCallback) {
|
|
|
- self.touchEndCallback(YES);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)setDrawColor:(NSColor *)drawColor
|
|
|
-{
|
|
|
- _drawColor = drawColor;
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)setStrokeRadius:(float)strokeRadius
|
|
|
-{
|
|
|
- _strokeRadius = strokeRadius;
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (NSImage *)signatureImage {
|
|
|
- CGRect rect = CGRectZero;
|
|
|
-
|
|
|
- if (self.bezierPath.empty) {
|
|
|
- return nil;
|
|
|
- } else {
|
|
|
- rect = self.bezierPath.bounds;
|
|
|
- }
|
|
|
-
|
|
|
- CGSize size = CGSizeMake(rect.size.width+self.bezierPath.lineWidth,
|
|
|
- rect.size.height+self.bezierPath.lineWidth);
|
|
|
- //修改崩溃 “签名,触摸板,再选中左下角触摸板,崩溃了”
|
|
|
- if (size.width <= 0 && size.height <= 0) {
|
|
|
- return nil;
|
|
|
- }
|
|
|
- NSImage *image = [[NSImage alloc] initWithSize:size];
|
|
|
- [image lockFocus];
|
|
|
-
|
|
|
- [self.drawColor set];
|
|
|
- [self.drawBezierPath setLineWidth:self.strokeRadius * 2];
|
|
|
- [self.drawBezierPath setLineCapStyle:kCGLineCapRound];
|
|
|
- [self.drawBezierPath setLineJoinStyle:kCGLineJoinRound];
|
|
|
- [self.drawBezierPath stroke];
|
|
|
-
|
|
|
- [image unlockFocus];
|
|
|
-
|
|
|
- return image;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark Draw
|
|
|
-- (void)drawRect:(NSRect)dirtyRect {
|
|
|
- [super drawRect:dirtyRect];
|
|
|
-
|
|
|
- [NSGraphicsContext saveGraphicsState];
|
|
|
- [[NSColor clearColor] set];
|
|
|
-
|
|
|
- if (([[self window] firstResponder] == self) && self.mouseIsInView) {
|
|
|
- NSSetFocusRingStyle(NSFocusRingAbove);
|
|
|
- }
|
|
|
- [[NSBezierPath bezierPathWithRect:[self bounds]] fill];
|
|
|
-
|
|
|
- [NSGraphicsContext restoreGraphicsState];
|
|
|
-
|
|
|
- if (self.drawImage) {
|
|
|
- CGRect imageFrame = [self imageFrameInRect:dirtyRect];
|
|
|
- [self.drawImage drawInRect:imageFrame];
|
|
|
- }
|
|
|
-
|
|
|
- [self.drawColor set];
|
|
|
- [self.bezierPath setLineWidth:self.strokeRadius * 2];
|
|
|
- [self.bezierPath setLineCapStyle:kCGLineCapRound];
|
|
|
- [self.bezierPath setLineJoinStyle:kCGLineJoinRound];
|
|
|
- [self.bezierPath stroke];
|
|
|
-}
|
|
|
-
|
|
|
-- (CGRect)imageFrameInRect:(CGRect)rect {
|
|
|
- CGRect imageRect;
|
|
|
- if (self.drawImage.size.width < rect.size.width &&
|
|
|
- self.drawImage.size.height < rect.size.height) {
|
|
|
- imageRect.origin.x = (rect.size.width-self.drawImage.size.width)/2.0;
|
|
|
- imageRect.origin.y = (rect.size.height-self.drawImage.size.height)/2.0;
|
|
|
- imageRect.size = self.drawImage.size;
|
|
|
- } else {
|
|
|
- if (self.drawImage.size.width/self.drawImage.size.height >
|
|
|
- rect.size.width/rect.size.height) {
|
|
|
- imageRect.size.width = rect.size.width;
|
|
|
- imageRect.size.height = rect.size.width*self.drawImage.size.height/self.drawImage.size.width;
|
|
|
- } else {
|
|
|
- imageRect.size.height = rect.size.height;
|
|
|
- imageRect.size.width = rect.size.height*self.drawImage.size.width/self.drawImage.size.height;
|
|
|
- }
|
|
|
- imageRect.origin.x = (rect.size.width-imageRect.size.width)/2.0;
|
|
|
- imageRect.origin.y = (rect.size.height-imageRect.size.height)/2.0;
|
|
|
- }
|
|
|
- return imageRect;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark Touch
|
|
|
-
|
|
|
-- (void)touchesBeganWithEvent:(NSEvent *)event
|
|
|
-{
|
|
|
- [super touchesBeganWithEvent:event];
|
|
|
-
|
|
|
- NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseBegan inView:self];
|
|
|
- self.activeTouch = [touches anyObject];
|
|
|
-
|
|
|
- CGPoint point = [self.activeTouch normalizedPosition];
|
|
|
- point.x = point.x * self.bounds.size.width;
|
|
|
- point.y = point.y * self.bounds.size.height;
|
|
|
- _index = 0;
|
|
|
- _points[0] = point;
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
-
|
|
|
- if (!self.cursorIsHidden) {
|
|
|
- CGAssociateMouseAndMouseCursorPosition(false);
|
|
|
-
|
|
|
- [NSCursor hide];
|
|
|
- self.cursorIsHidden = YES;
|
|
|
- }
|
|
|
-
|
|
|
- if (self.changeDrawCallback) {
|
|
|
- self.changeDrawCallback(YES);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)touchesMovedWithEvent:(NSEvent *)event
|
|
|
-{
|
|
|
- [super touchesMovedWithEvent:event];
|
|
|
-
|
|
|
- NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseMoved inView:self];
|
|
|
-
|
|
|
- BOOL isTouch = NO;
|
|
|
- for (NSTouch *touch in touches) {
|
|
|
- if (touch.identity == self.activeTouch.identity) {
|
|
|
- isTouch = YES;
|
|
|
- self.activeTouch = touch;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!isTouch) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- NSPoint point = [self.activeTouch normalizedPosition];
|
|
|
- point.x = point.x * self.bounds.size.width;
|
|
|
- point.y = point.y * self.bounds.size.height;
|
|
|
-
|
|
|
- _index++;
|
|
|
- _points[_index] = point;
|
|
|
-
|
|
|
- if (_index == 4) {
|
|
|
- _points[3] = CGPointMake((_points[2].x + _points[4].x)/2.0,
|
|
|
- (_points[2].y + _points[4].y)/2.0);
|
|
|
- [self.bezierPath moveToPoint:_points[0]];
|
|
|
-
|
|
|
- [self.bezierPath curveToPoint:_points[3]
|
|
|
- controlPoint1:_points[1]
|
|
|
- controlPoint2:_points[2] ];
|
|
|
- _points[0] = _points[3];
|
|
|
- _points[1] = _points[4];
|
|
|
- _index = 1;
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)touchesEndedWithEvent:(NSEvent *)event
|
|
|
-{
|
|
|
- [super touchesEndedWithEvent:event];
|
|
|
-
|
|
|
- NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseMoved inView:self];
|
|
|
-
|
|
|
- for (NSTouch *touch in touches) {
|
|
|
- if (touch.identity == self.activeTouch.identity) {
|
|
|
- self.activeTouch = nil;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (_index < 4) {
|
|
|
- for (int i=0; i<_index; i++) {
|
|
|
- [self.bezierPath moveToPoint:_points[i]];
|
|
|
- }
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
- }
|
|
|
-
|
|
|
-// NSImage *image = [self signatureImage];
|
|
|
-// if (self.changeDrawCallback) {
|
|
|
-// self.changeDrawCallback(image);
|
|
|
-// }
|
|
|
- if (self.touchEndCallback) {
|
|
|
- self.touchEndCallback(NO);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)touchesCancelledWithEvent:(NSEvent *)event
|
|
|
-{
|
|
|
- [super touchesCancelledWithEvent:event];
|
|
|
-
|
|
|
- for (int i=0; i<_index; i++) {
|
|
|
- [self.bezierPath moveToPoint:_points[i]];
|
|
|
- }
|
|
|
- self.activeTouch = nil;
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark Mouse
|
|
|
-- (void)viewDidMoveToWindow
|
|
|
-{
|
|
|
- if ([self window] != nil) {
|
|
|
- [self addTrackingRect:[self bounds]
|
|
|
- owner:self
|
|
|
- userData:NULL
|
|
|
- assumeInside:NO];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)mouseEntered:(NSEvent *)theEvent
|
|
|
-{
|
|
|
- [[self window] makeFirstResponder:self];
|
|
|
-
|
|
|
-// self.mouseIsInView = YES;
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)mouseExited:(NSEvent *)theEvent
|
|
|
-{
|
|
|
-// self.mouseIsInView = NO;
|
|
|
-
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)mouseDown:(NSEvent *)theEvent
|
|
|
-{
|
|
|
- if ([self acceptsTouchEvents]) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- CGPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
|
|
- _index = 0;
|
|
|
- _points[0] = point;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)mouseDragged:(NSEvent *)theEvent
|
|
|
-{
|
|
|
- if ([self acceptsTouchEvents]) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
|
|
-
|
|
|
- _index++;
|
|
|
- _points[_index] = point;
|
|
|
-
|
|
|
- if (_index == 4) {
|
|
|
- _points[3] = CGPointMake((_points[2].x + _points[4].x)/2.0,
|
|
|
- (_points[2].y + _points[4].y)/2.0);
|
|
|
- [self.bezierPath moveToPoint:_points[0]];
|
|
|
-
|
|
|
- [self.bezierPath curveToPoint:_points[3]
|
|
|
- controlPoint1:_points[1]
|
|
|
- controlPoint2:_points[2] ];
|
|
|
- _points[0] = _points[3];
|
|
|
- _points[1] = _points[4];
|
|
|
- _index = 1;
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
-
|
|
|
- if (self.changeDrawCallback) {
|
|
|
- self.changeDrawCallback(YES);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)mouseUp:(NSEvent *)theEvent
|
|
|
-{
|
|
|
- if ([self acceptsTouchEvents]) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (_index < 4) {
|
|
|
- for (int i=0; i<_index; i++) {
|
|
|
- [self.bezierPath moveToPoint:_points[i]];
|
|
|
- }
|
|
|
- [self setNeedsDisplay:YES];
|
|
|
- }
|
|
|
- if (self.touchEndCallback) {
|
|
|
- self.touchEndCallback(NO);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)keyDown:(NSEvent *)theEvent
|
|
|
-{
|
|
|
- NSString *chars = [theEvent characters];
|
|
|
- if(chars.length > 0) {
|
|
|
- unichar character = [chars characterAtIndex:0];
|
|
|
-
|
|
|
-// if (character == 27) {
|
|
|
- if (self.isAcceptsTouch) {
|
|
|
- self.isAcceptsTouch = NO;
|
|
|
- if ([self.delegate respondsToSelector:@selector(drawViewDidFinishTouchMode:)]) {
|
|
|
- [self.delegate drawViewDidFinishTouchMode:self];
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
-// }
|
|
|
- }
|
|
|
-
|
|
|
- [super keyDown:theEvent];
|
|
|
-}
|
|
|
-
|
|
|
-@end
|