// // KMLineWell.swift // PDF Master // // Created by tangchao on 2023/11/6. // import Cocoa private let SKLineWellLineWidthKey = "lineWidth" private let SKLineWellStyleKey = "style" private let SKLineWellDashPatternKey = "dashPattern" private let SKLineWellStartLineStyleKey = "startLineStyle" private let SKLineWellEndLineStyleKey = "endLineStyle" private let ACTION_KEY = "action" private let TARGET_KEY = "target" class KMLineWell: NSControl { public static let widthKey = SKLineWellLineWidthKey public static let styleKey = SKLineWellStyleKey public static let dashPatternKey = SKLineWellDashPatternKey public static let startLineStyleKey = SKLineWellStartLineStyleKey public static let endLineStyleKey = SKLineWellEndLineStyleKey var lineWidth: CGFloat = 0 var style: CPDFBorderStyle = .solid var startLineStyle: CPDFLineStyle = .none var endLineStyle: CPDFLineStyle = .none struct _lwFlags { var displayStyle: UInt } /* extern NSString *SKPasteboardTypeLineStyle; // these keys are used in the userInfo dictionary of this pboard type extern NSString *SKLineWellLineWidthKey; extern NSString *SKLineWellStyleKey; extern NSString *SKLineWellDashPatternKey; extern NSString *SKLineWellStartLineStyleKey; extern NSString *SKLineWellEndLineStyleKey; typedef NS_ENUM(NSInteger, SKLineWellDisplayStyle) { SKLineWellDisplayStyleLine, SKLineWellDisplayStyleSimpleLine, SKLineWellDisplayStyleRectangle, SKLineWellDisplayStyleOval }; @interface SKLineWell : NSControl { NSArray *dashPattern; struct _lwFlags { unsigned int displayStyle:2; unsigned int active:1; unsigned int canActivate:1; unsigned int existsActiveLineWell:1; unsigned int highlighted:1; } lwFlags; id target; SEL action; } @property (nonatomic, readonly) BOOL isActive; @property (nonatomic) BOOL ; @property (nonatomic) SKLineWellDisplayStyle displayStyle; @property (nonatomic) CGFloat lineWidth; @property (nonatomic) PDFBorderStyle style; @property (nonatomic, copy) NSArray *dashPattern; @property (nonatomic) PDFLineStyle startLineStyle, endLineStyle; - (void)activate:(BOOL)exclusive; - (void)deactivate; - (void)lineInspectorLineAttributeChanged:(NSNotification *)notification; @end */ // var canActivate = false { // - (BOOL)canActivate { // return lwFlags.canActivate; // } // // - (void)setCanActivate:(BOOL)flag { // if (lwFlags.canActivate != flag) { // lwFlags.canActivate = flag; // if ([self isActive] && lwFlags.canActivate == 0) // [self deactivate]; // } // } // } override init(frame frameRect: NSRect) { super.init(frame: frameRect) lineWidth = 1.0 style = .solid // dashPattern = nil; startLineStyle = .none endLineStyle = .none // lwFlags.displayStyle = SKLineWellDisplayStyleLine; // lwFlags.active = 0; // lwFlags.canActivate = 0; // lwFlags.existsActiveLineWell = 0; self.target = nil self.action = nil self._commonInit() } required init?(coder: NSCoder) { super.init(coder: coder) lineWidth = coder.decodeDouble(forKey: SKLineWellLineWidthKey) style = CPDFBorderStyle(rawValue: coder.decodeInteger(forKey: SKLineWellStyleKey)) ?? .solid // dashPattern = [decoder decodeObjectForKey:SKLineWellDashPatternKey]; startLineStyle = CPDFLineStyle(rawValue: coder.decodeInteger(forKey: SKLineWellStartLineStyleKey)) ?? .none endLineStyle = CPDFLineStyle(rawValue: coder.decodeInteger(forKey: SKLineWellEndLineStyleKey)) ?? .none // lwFlags.displayStyle = [decoder decodeIntegerForKey:DISPLAYSTYLE_KEY]; // lwFlags.active = [decoder decodeBoolForKey:ACTIVE_KEY]; action = NSSelectorFromString(coder.decodeObject(forKey: ACTION_KEY) as? String ?? "") target = coder.decodeObject(forKey: TARGET_KEY) as AnyObject? self._commonInit() } override func encode(with coder: NSCoder) { super.encode(with: coder) coder.encode(lineWidth, forKey: SKLineWellLineWidthKey) coder.encode(style.rawValue, forKey: SKLineWellStyleKey) // [coder encodeObject:dashPattern forKey:SKLineWellDashPatternKey]; coder.encode(startLineStyle.rawValue, forKey: SKLineWellStartLineStyleKey) coder.encode(endLineStyle.rawValue, forKey: SKLineWellEndLineStyleKey) // [coder encodeInteger:(NSInteger)(lwFlags.displayStyle) forKey:DISPLAYSTYLE_KEY]; // [coder encodeBool:(BOOL)(lwFlags.active) forKey:ACTIVE_KEY]; if let data = self.action { coder.encode(NSStringFromSelector(data), forKey: ACTION_KEY) } coder.encode(target, forKey: TARGET_KEY) } override var isOpaque: Bool { return true } // override var acceptsFirstResponder: Bool { // return self. // } /* - (BOOL)acceptsFirstResponder { return [self canActivate]; } - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return [self canActivate]; } - (void)viewWillMoveToWindow:(NSWindow *)newWindow { [self deactivate]; [super viewWillMoveToWindow:newWindow]; } */ override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) // Drawing code here. } /* NSString *SKPasteboardTypeLineStyle = @"net.sourceforge.skim-app.pasteboard.line-style"; #define DISPLAYSTYLE_KEY @"lwFlags.displayStyle" #define ACTIVE_KEY @"active" #define SKLineWellWillBecomeActiveNotification @"SKLineWellWillBecomeActiveNotification" #define EXCLUSIVE_KEY @"exclusive" @implementation SKLineWell @synthesize lineWidth, style, dashPattern, startLineStyle, endLineStyle; @dynamic isActive, canActivate, displayStyle; + (void)initialize { // SKINITIALIZE; [self exposeBinding:SKLineWellLineWidthKey]; [self exposeBinding:SKLineWellStyleKey]; [self exposeBinding:SKLineWellDashPatternKey]; [self exposeBinding:SKLineWellStartLineStyleKey]; [self exposeBinding:SKLineWellEndLineStyleKey]; } - (Class)valueClassForBinding:(NSString *)binding { if ([binding isEqualToString:SKLineWellDashPatternKey]) return [NSArray class]; else return [NSNumber class]; } - (void)dealloc { // SKENSURE_MAIN_THREAD( [self unbind:SKLineWellLineWidthKey]; [self unbind:SKLineWellStyleKey]; [self unbind:SKLineWellDashPatternKey]; [self unbind:SKLineWellStartLineStyleKey]; [self unbind:SKLineWellEndLineStyleKey]; // ); [[NSNotificationCenter defaultCenter] removeObserver:self]; // SKDESTROY(dashPattern); // [super dealloc]; } - (NSBezierPath *)path { NSBezierPath *path = [NSBezierPath bezierPath]; NSRect bounds = [self bounds]; if ([self displayStyle] == SKLineWellDisplayStyleLine) { CGFloat offset = 0.5 * lineWidth - floor(0.5 * lineWidth); NSPoint startPoint = NSMakePoint(NSMinX(bounds) + ceil(0.5 * NSHeight(bounds)), round(NSMidY(bounds)) - offset); NSPoint endPoint = NSMakePoint(NSMaxX(bounds) - ceil(0.5 * NSHeight(bounds)), round(NSMidY(bounds)) - offset); switch (startLineStyle) { case kPDFLineStyleNone: break; case kPDFLineStyleSquare: [path appendBezierPathWithRect:NSMakeRect(startPoint.x - 1.5 * lineWidth, startPoint.y - 1.5 * lineWidth, 3 * lineWidth, 3 * lineWidth)]; break; case kPDFLineStyleCircle: [path appendBezierPathWithOvalInRect:NSMakeRect(startPoint.x - 1.5 * lineWidth, startPoint.y - 1.5 * lineWidth, 3 * lineWidth, 3 * lineWidth)]; break; case kPDFLineStyleDiamond: [path moveToPoint:NSMakePoint(startPoint.x - 1.5 * lineWidth, startPoint.y)]; [path lineToPoint:NSMakePoint(startPoint.x, startPoint.y + 1.5 * lineWidth)]; [path lineToPoint:NSMakePoint(startPoint.x + 1.5 * lineWidth, startPoint.y)]; [path lineToPoint:NSMakePoint(startPoint.x, startPoint.y - 1.5 * lineWidth)]; [path closePath]; break; case kPDFLineStyleOpenArrow: [path moveToPoint:NSMakePoint(startPoint.x + 3.0 * lineWidth, startPoint.y - 1.5 * lineWidth)]; [path lineToPoint:NSMakePoint(startPoint.x, startPoint.y)]; [path lineToPoint:NSMakePoint(startPoint.x + 3.0 * lineWidth, startPoint.y + 1.5 * lineWidth)]; break; case kPDFLineStyleClosedArrow: [path moveToPoint:NSMakePoint(startPoint.x + 3.0 * lineWidth, startPoint.y - 1.5 * lineWidth)]; [path lineToPoint:NSMakePoint(startPoint.x, startPoint.y)]; [path lineToPoint:NSMakePoint(startPoint.x + 3.0 * lineWidth, startPoint.y + 1.5 * lineWidth)]; [path closePath]; break; } [path moveToPoint:startPoint]; [path lineToPoint:endPoint]; switch (endLineStyle) { case kPDFLineStyleNone: break; case kPDFLineStyleSquare: [path appendBezierPathWithRect:NSMakeRect(endPoint.x - 1.5 * lineWidth, endPoint.y - 1.5 * lineWidth, 3 * lineWidth, 3 * lineWidth)]; break; case kPDFLineStyleCircle: [path appendBezierPathWithOvalInRect:NSMakeRect(endPoint.x - 1.5 * lineWidth, endPoint.y - 1.5 * lineWidth, 3 * lineWidth, 3 * lineWidth)]; break; case kPDFLineStyleDiamond: [path moveToPoint:NSMakePoint(endPoint.x + 1.5 * lineWidth, endPoint.y)]; [path lineToPoint:NSMakePoint(endPoint.x, endPoint.y + 1.5 * lineWidth)]; [path lineToPoint:NSMakePoint(endPoint.x - 1.5 * lineWidth, endPoint.y)]; [path lineToPoint:NSMakePoint(endPoint.x, endPoint.y - 1.5 * lineWidth)]; [path closePath]; break; case kPDFLineStyleOpenArrow: [path moveToPoint:NSMakePoint(endPoint.x - 3.0 * lineWidth, endPoint.y + 1.5 * lineWidth)]; [path lineToPoint:NSMakePoint(endPoint.x, endPoint.y)]; [path lineToPoint:NSMakePoint(endPoint.x - 3.0 * lineWidth, endPoint.y - 1.5 * lineWidth)]; break; case kPDFLineStyleClosedArrow: [path moveToPoint:NSMakePoint(endPoint.x - 3.0 * lineWidth, endPoint.y + 1.5 * lineWidth)]; [path lineToPoint:NSMakePoint(endPoint.x, endPoint.y)]; [path lineToPoint:NSMakePoint(endPoint.x - 3.0 * lineWidth, endPoint.y - 1.5 * lineWidth)]; [path closePath]; break; } } else if ([self displayStyle] == SKLineWellDisplayStyleSimpleLine) { CGFloat offset = 0.5 * lineWidth - floor(0.5 * lineWidth); [path moveToPoint:NSMakePoint(NSMinX(bounds) + ceil(0.5 * NSHeight(bounds)), round(NSMidY(bounds)) - offset)]; [path lineToPoint:NSMakePoint(NSMaxX(bounds) - ceil(0.5 * NSHeight(bounds)), round(NSMidY(bounds)) - offset)]; } else if ([self displayStyle] == SKLineWellDisplayStyleRectangle) { CGFloat inset = 7.0 + 0.5 * lineWidth; [path appendBezierPathWithRect:NSInsetRect(bounds, inset, inset)]; } else { CGFloat inset = 7.0 + 0.5 * lineWidth; [path appendBezierPathWithOvalInRect:NSInsetRect(bounds, inset, inset)]; } [path setLineWidth:lineWidth]; // if (style == kPDFBorderStyleDashed) // [path setDashPattern:dashPattern]; return path; } - (void)drawRect:(NSRect)rect { NSRect bounds = [self bounds]; // SKDrawTextFieldBezel(bounds, self); if ([self isActive]) { [NSGraphicsContext saveGraphicsState]; [[NSColor selectedControlColor] setFill]; NSRectFillUsingOperation(bounds, NSCompositePlusDarker); [NSGraphicsContext restoreGraphicsState]; } if ([self isHighlighted]) { [NSGraphicsContext saveGraphicsState]; [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] setFill]; NSFrameRectWithWidthUsingOperation([self bounds], 1.0, NSCompositePlusDarker); [NSGraphicsContext restoreGraphicsState]; } if (lineWidth > 0.0) { [NSGraphicsContext saveGraphicsState]; [[NSBezierPath bezierPathWithRect:NSInsetRect(bounds, 2.0, 2.0)] addClip]; [[NSColor blackColor] setStroke]; [[self path] stroke]; [NSGraphicsContext restoreGraphicsState]; } if ([self refusesFirstResponder] == NO && [NSApp isActive] && [[self window] isKeyWindow] && [[self window] firstResponder] == self) { [NSGraphicsContext saveGraphicsState]; NSSetFocusRingStyle(NSFocusRingOnly); NSRectFill(bounds); [NSGraphicsContext restoreGraphicsState]; } } - (NSImage *)dragImage { NSRect bounds = [self bounds]; NSBezierPath *path = lineWidth > 0.0 ? [self path] : nil; // CGFloat scale = [self backingScale]; CGFloat scale = 1; NSImage *image = [NSImage bitmapImageWithSize:bounds.size scale:scale drawingHandler:^(NSRect rect){ CGContextSetAlpha([[NSGraphicsContext currentContext] graphicsPort], 0.7); [[NSColor darkGrayColor] setFill]; NSRectFill(NSInsetRect(rect, 1.0, 1.0)); [[NSColor controlBackgroundColor] setFill]; NSRectFill(NSInsetRect(rect, 2.0, 2.0)); [[NSColor blackColor] setStroke]; [path stroke]; }]; return image; } - (void)changedValueForKey:(NSString *)key { if ([self isActive]) // [[SKLineInspector sharedLineInspector] setValue:[self valueForKey:key] forKey:key]; [self setNeedsDisplay:YES]; } - (void)takeValueForKey:(NSString *)key from:(id)object { [self setValue:[object valueForKey:key] forKey:key]; NSDictionary *info = [self infoForBinding:key]; [[info objectForKey:NSObservedObjectKey] setValue:[self valueForKey:key] forKeyPath:[info objectForKey:NSObservedKeyPathKey]]; } - (void)mouseDown:(NSEvent *)theEvent { if ([self isEnabled]) { [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; [self setNeedsDisplay:YES]; NSUInteger modifiers = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; BOOL keepOn = YES; while (keepOn) { theEvent = [[self window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask]; switch ([theEvent type]) { case NSLeftMouseDragged: { NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithDouble:lineWidth], SKLineWellLineWidthKey, [NSNumber numberWithInteger:style], SKLineWellStyleKey, dashPattern, SKLineWellDashPatternKey, nil]; if ([self displayStyle] == SKLineWellDisplayStyleLine) { [dict setObject:[NSNumber numberWithInteger:startLineStyle] forKey:SKLineWellStartLineStyleKey]; [dict setObject:[NSNumber numberWithInteger:endLineStyle] forKey:SKLineWellEndLineStyleKey]; } NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; [pboard clearContents]; [pboard setPropertyList:dict forType:SKPasteboardTypeLineStyle]; NSRect bounds = [self bounds]; [self dragImage:[self dragImage] at:bounds.origin offset:NSZeroSize event:theEvent pasteboard:pboard source:self slideBack:YES]; keepOn = NO; break; } case NSLeftMouseUp: if ([self isActive]) [self deactivate]; else [self activate:(modifiers & NSShiftKeyMask) == 0]; keepOn = NO; break; default: break; } } } } - (void)performClick:(id)sender { if ([self isEnabled]) { if ([self isActive]) [self deactivate]; else [self activate:YES]; } } - (void)existsActiveLineWell { lwFlags.existsActiveLineWell = 1; } - (void)lineWellWillBecomeActive:(NSNotification *)notification { id sender = [notification object]; if (sender != self && [self isActive]) { if ([[[notification userInfo] valueForKey:EXCLUSIVE_KEY] boolValue]) [self deactivate]; else [sender existsActiveLineWell]; } } - (void)lineInspectorWindowWillClose:(NSNotification *)notification { [self deactivate]; } - (void)activate:(BOOL)exclusive { if ([self canActivate]) { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; // SKLineInspector *inspector = [SKLineInspector sharedLineInspector]; lwFlags.existsActiveLineWell = 0; [nc postNotificationName:SKLineWellWillBecomeActiveNotification object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:exclusive], EXCLUSIVE_KEY, nil]]; if (lwFlags.existsActiveLineWell) { // [self takeValueForKey:SKLineWellLineWidthKey from:inspector]; // [self takeValueForKey:SKLineWellDashPatternKey from:inspector]; // [self takeValueForKey:SKLineWellStyleKey from:inspector]; if ([self displayStyle] == SKLineWellDisplayStyleLine) { // [self takeValueForKey:SKLineWellStartLineStyleKey from:inspector]; // [self takeValueForKey:SKLineWellEndLineStyleKey from:inspector]; } } else { // [inspector setLineWidth:[self lineWidth]]; // [inspector setDashPattern:[self dashPattern]]; // [inspector setStyle:[self style]]; if ([self displayStyle] == SKLineWellDisplayStyleLine) { // [inspector setStartLineStyle:[self startLineStyle]]; // [inspector setEndLineStyle:[self endLineStyle]]; } } // [[inspector window] orderFront:self]; [nc addObserver:self selector:@selector(lineWellWillBecomeActive:) name:SKLineWellWillBecomeActiveNotification object:nil]; // [nc addObserver:self selector:@selector(lineInspectorWindowWillClose:) // name:NSWindowWillCloseNotification object:[inspector window]]; // [nc addObserver:self selector:@selector(lineInspectorLineAttributeChanged:) // name:SKLineInspectorLineAttributeDidChangeNotification object:inspector]; lwFlags.active = 1; [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; [self setNeedsDisplay:YES]; } } - (void)deactivate { if ([self isActive]) { [[NSNotificationCenter defaultCenter] removeObserver:self]; lwFlags.active = 0; [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; [self setNeedsDisplay:YES]; } } #pragma mark Accessors - (SEL)action { return action; } - (void)setAction:(SEL)newAction { action = newAction; } - (id)target { return target; } - (void)setTarget:(id)newTarget { target = newTarget; } - (BOOL)isActive { return lwFlags.active; } - (BOOL)isHighlighted { return lwFlags.highlighted; } - (void)setHighlighted:(BOOL)flag { if (lwFlags.highlighted != flag) { lwFlags.highlighted = flag; } } - (SKLineWellDisplayStyle)displayStyle { return lwFlags.displayStyle; } - (void)setDisplayStyle:(SKLineWellDisplayStyle)newStyle { if (lwFlags.displayStyle != newStyle) { lwFlags.displayStyle = newStyle; [self setNeedsDisplay:YES]; } } - (void)setLineWidth:(CGFloat)width { if (fabs(lineWidth - width) > 0.00001) { lineWidth = width; [self changedValueForKey:SKLineWellLineWidthKey]; } } - (void)setStyle:(PDFBorderStyle)newStyle { if (newStyle != style) { style = newStyle; [self changedValueForKey:SKLineWellStyleKey]; } } - (void)setDashPattern:(NSArray *)pattern { if (NSIsControllerMarker(pattern)) pattern = nil; if ([pattern isEqualToArray:dashPattern] == NO && (pattern || dashPattern)) { dashPattern = pattern; [self changedValueForKey:SKLineWellDashPatternKey]; } } - (void)setStartLineStyle:(PDFLineStyle)newStyle { if (newStyle != startLineStyle) { startLineStyle = newStyle; [self changedValueForKey:SKLineWellStartLineStyleKey]; } } - (void)setEndLineStyle:(PDFLineStyle)newStyle { if (newStyle != endLineStyle) { endLineStyle = newStyle; [self changedValueForKey:SKLineWellEndLineStyleKey]; } } - (void)setNilValueForKey:(NSString *)key { if ([key isEqualToString:SKLineWellLineWidthKey] || [key isEqualToString:SKLineWellStyleKey] || [key isEqualToString:SKLineWellStartLineStyleKey] || [key isEqualToString:SKLineWellEndLineStyleKey]) { [self setValue:[NSNumber numberWithInteger:0] forKey:key]; } else { [super setNilValueForKey:key]; } } #pragma mark Notification handlers - (void)lineInspectorLineAttributeChanged:(NSNotification *)notification { // SKLineInspector *inspector = [notification object]; // NSString *key = nil; // switch ([inspector currentLineChangeAction]) { // case SKLineChangeActionLineWidth: // key = SKLineWellLineWidthKey; // break; // case SKLineChangeActionStyle: // key = SKLineWellStyleKey; // break; // case SKLineChangeActionDashPattern: // key = SKLineWellDashPatternKey; // break; // case SKLineChangeActionStartLineStyle: // if ([self displayStyle] == SKLineWellDisplayStyleLine) // key = SKLineWellStartLineStyleKey; // break; // case SKLineChangeActionEndLineStyle: // if ([self displayStyle] == SKLineWellDisplayStyleLine) // key = SKLineWellEndLineStyleKey; // break; // case SKNoLineChangeAction: // break; // } // if (key) { // [self takeValueForKey:key from:inspector]; // [self sendAction:[self action] to:[self target]]; // } } #pragma mark NSDraggingSource protocol - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { return NSDragOperationGeneric; } #pragma mark NSDraggingDestination protocol - (NSDragOperation)draggingEntered:(id )sender { if ([self isEnabled] && [sender draggingSource] != self && [[sender draggingPasteboard] canReadItemWithDataConformingToTypes:[NSArray arrayWithObjects:SKPasteboardTypeLineStyle, nil]]) { [self setHighlighted:YES]; [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; [self setNeedsDisplay:YES]; return NSDragOperationEvery; } else return NSDragOperationNone; } - (void)draggingExited:(id )sender { if ([self isEnabled] && [sender draggingSource] != self && [[sender draggingPasteboard] canReadItemWithDataConformingToTypes:[NSArray arrayWithObjects:SKPasteboardTypeLineStyle, nil]]) { [self setHighlighted:NO]; [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; [self setNeedsDisplay:YES]; } } - (BOOL)prepareForDragOperation:(id )sender { return [self isEnabled] && [sender draggingSource] != self && [[sender draggingPasteboard] canReadItemWithDataConformingToTypes:[NSArray arrayWithObjects:SKPasteboardTypeLineStyle, nil]]; } - (BOOL)performDragOperation:(id )sender{ NSPasteboard *pboard = [sender draggingPasteboard]; [pboard types]; NSDictionary *dict = [pboard propertyListForType:SKPasteboardTypeLineStyle]; if ([dict objectForKey:SKLineWellLineWidthKey]) [self takeValueForKey:SKLineWellLineWidthKey from:dict]; if ([dict objectForKey:SKLineWellStyleKey]) [self takeValueForKey:SKLineWellStyleKey from:dict]; [self takeValueForKey:SKLineWellDashPatternKey from:dict]; if ([self displayStyle] == SKLineWellDisplayStyleLine) { if ([dict objectForKey:SKLineWellStartLineStyleKey]) [self takeValueForKey:SKLineWellStartLineStyleKey from:dict]; if ([dict objectForKey:SKLineWellEndLineStyleKey]) [self takeValueForKey:SKLineWellEndLineStyleKey from:dict]; } [self sendAction:[self action] to:[self target]]; [self setHighlighted:NO]; [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; [self setNeedsDisplay:YES]; return dict != nil; } #pragma mark Accessibility - (NSArray *)accessibilityAttributeNames { static NSArray *attributes = nil; if (attributes == nil) { attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilityValueAttribute, NSAccessibilityTitleAttribute, NSAccessibilityHelpAttribute, NSAccessibilityFocusedAttribute, NSAccessibilityParentAttribute, NSAccessibilityWindowAttribute, NSAccessibilityTopLevelUIElementAttribute, NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, nil]; } return attributes; } - (id)accessibilityAttributeValue:(NSString *)attribute { if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { return NSAccessibilityCheckBoxRole; } else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { return NSAccessibilityRoleDescription(NSAccessibilityCheckBoxRole, nil); } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { return [NSNumber numberWithInteger:[self isActive]]; } else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) { return [NSString stringWithFormat:@"%@ %ld", NSLocalizedString(@"line width", @"Accessibility description"), (long)[self lineWidth]]; } else if ([attribute isEqualToString:NSAccessibilityHelpAttribute]) { return [self toolTip]; } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { // Just check if the app thinks we're focused. id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute]; return [NSNumber numberWithBool:[focusedElement isEqual:self]]; } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { return NSAccessibilityUnignoredAncestor([self superview]); } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) { // We're in the same window as our parent. return [NSAccessibilityUnignoredAncestor([self superview]) accessibilityAttributeValue:NSAccessibilityWindowAttribute]; } else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) { // We're in the same top level element as our parent. return [NSAccessibilityUnignoredAncestor([self superview]) accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { return [NSValue valueWithPoint:[[self window] convertBaseToScreen:[self convertPoint:[self bounds].origin toView:nil]]]; } else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) { return [NSValue valueWithSize:[self convertSize:[self bounds].size toView:nil]]; } else { return nil; } } - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { return [self canActivate]; } else { return NO; } } - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { [[self window] makeFirstResponder:self]; } } // actions - (NSArray *)accessibilityActionNames { return [NSArray arrayWithObject:NSAccessibilityPressAction]; } - (NSString *)accessibilityActionDescription:(NSString *)anAction { return NSAccessibilityActionDescription(anAction); } - (void)accessibilityPerformAction:(NSString *)anAction { if ([anAction isEqualToString:NSAccessibilityPressAction]) [self performClick:self]; } // misc - (BOOL)accessibilityIsIgnored { return NO; } - (id)accessibilityHitTest:(NSPoint)point { return NSAccessibilityUnignoredAncestor(self); } - (id)accessibilityFocusedUIElement { return NSAccessibilityUnignoredAncestor(self); } @end */ } // MARK: - Private Methods extension KMLineWell { private func _commonInit() { // lwFlags.canActivate = 1; // lwFlags.existsActiveLineWell = 0; // [self registerForDraggedTypes:[NSArray arrayWithObjects:SKPasteboardTypeLineStyle, nil]]; } /* */ }