gngrwzrd

NSTextField Edit in Place No NSCell

Apr 22nd, 2015
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #import <Cocoa/Cocoa.h>
  3.  
  4. @interface EditTextField : NSTextField <NSTextDelegate,NSTextViewDelegate,NSTextFieldDelegate>
  5.  
  6. @property BOOL isEditing;
  7. @property BOOL commitChangesOnEscapeKey;
  8. @property BOOL editAfterDelay;
  9. @property CGFloat delay;
  10.  
  11. @end
  12.  
  13. ----
  14.  
  15.  
  16. #import "EditTextField.h"
  17.  
  18. @interface EditTextField ()
  19. @property NSObject <NSTextFieldDelegate,NSTextViewDelegate> * userDelegate;
  20. @property NSString * originalStringValue;
  21. @property NSTimer * editTimer;
  22. @property NSTrackingArea * editTrackingArea;
  23. @end
  24.  
  25. @implementation EditTextField
  26.  
  27. - (id) initWithCoder:(NSCoder *)coder {
  28.     self = [super initWithCoder:coder];
  29.     [self defaultInit];
  30.     return self;
  31. }
  32.  
  33. - (id) initWithFrame:(NSRect)frameRect {
  34.     self = [super initWithFrame:frameRect];
  35.     [self defaultInit];
  36.     return self;
  37. }
  38.  
  39. - (id) init {
  40.     self = [super init];
  41.     [self defaultInit];
  42.     return self;
  43. }
  44.  
  45. - (void) defaultInit {
  46.     self.delay = .8;
  47. }
  48.  
  49. - (void) mouseDown:(NSEvent *) theEvent {
  50.     if(theEvent.clickCount == 2) {
  51.         [self startEditing];
  52.     } else {
  53.         [super mouseDown:theEvent];
  54.         if(self.editAfterDelay) {
  55.             [self startTracking];
  56.             self.editTimer = [NSTimer scheduledTimerWithTimeInterval:.8 target:self selector:@selector(startEditing) userInfo:nil repeats:FALSE];
  57.         }
  58.     }
  59. }
  60.  
  61. - (void) startTracking {
  62.     if(!self.editTrackingArea) {
  63.         self.editTrackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseEnteredAndExited|NSTrackingMouseMoved|NSTrackingActiveInActiveApp|NSTrackingAssumeInside|NSTrackingInVisibleRect owner:self userInfo:nil];
  64.     }
  65.     [self addTrackingArea:self.editTrackingArea];
  66. }
  67.  
  68. - (void) mouseExited:(NSEvent *)theEvent {
  69.     [self.editTimer invalidate];
  70.     self.editTimer = nil;
  71. }
  72.  
  73. - (void) mouseMoved:(NSEvent *) theEvent {
  74.     [self.editTimer invalidate];
  75.     self.editTimer = nil;
  76. }
  77.  
  78. - (void) startEditing {
  79.     id firstResponder = self.window.firstResponder;
  80.     if([firstResponder isKindOfClass:[NSTextView class]]) {
  81.         NSTextView * tv = (NSTextView *)firstResponder;
  82.         if(tv.delegate && [tv.delegate isKindOfClass:[EditTextField class]]) {
  83.             EditTextField * fr = (EditTextField *)tv.delegate;
  84.             [fr stopEditingCommitChanges:FALSE clearFirstResponder:FALSE];
  85.         }
  86.     }
  87.     if(self.delegate != self) {
  88.         self.userDelegate = (NSObject <NSTextFieldDelegate,NSTextViewDelegate> *)self.delegate;
  89.     }
  90.     self.isEditing = TRUE;
  91.     self.delegate = self;
  92.     self.editable = TRUE;
  93.     self.originalStringValue = self.stringValue;
  94.     [self.window makeFirstResponder:self];
  95. }
  96.  
  97. - (void) stopEditingCommitChanges:(BOOL) commitChanges clearFirstResponder:(BOOL) clearFirstResponder {
  98.     self.editable = FALSE;
  99.     self.isEditing = FALSE;
  100.     self.delegate = nil;
  101.     [self removeTrackingArea:self.editTrackingArea];
  102.     if(!commitChanges) {
  103.         self.stringValue = self.originalStringValue;
  104.     }
  105.     if(clearFirstResponder) {
  106.         [self.window makeFirstResponder:nil];
  107.     }
  108. }
  109.  
  110. - (void) cancelOperation:(id) sender {
  111.     if(self.commitChangesOnEscapeKey) {
  112.         [self stopEditingCommitChanges:TRUE clearFirstResponder:TRUE];
  113.     } else {
  114.         [self stopEditingCommitChanges:FALSE clearFirstResponder:TRUE];
  115.     }
  116. }
  117.  
  118. - (BOOL) textView:(NSTextView *) textView doCommandBySelector:(SEL) commandSelector {
  119.     BOOL handlesCommand = FALSE;
  120.     NSString * selector = NSStringFromSelector(commandSelector);
  121.    
  122.     if(self.userDelegate) {
  123.        
  124.         if([self.userDelegate respondsToSelector:@selector(control:textView:doCommandBySelector:)]) {
  125.             handlesCommand = [self.userDelegate control:self textView:textView doCommandBySelector:commandSelector];
  126.         } else if([self.userDelegate respondsToSelector:@selector(textView:doCommandBySelector:)]) {
  127.             handlesCommand = [self.userDelegate textView:textView doCommandBySelector:commandSelector];
  128.         }
  129.        
  130.         if(!handlesCommand) {
  131.            
  132.             if([selector isEqualToString:@"insertNewline:"]) {
  133.                 [self stopEditingCommitChanges:TRUE clearFirstResponder:TRUE];
  134.                 handlesCommand = TRUE;
  135.             }
  136.            
  137.             if([selector isEqualToString:@"insertTab:"]) {
  138.                 [self stopEditingCommitChanges:TRUE clearFirstResponder:FALSE];
  139.                 handlesCommand = FALSE;
  140.             }
  141.         }
  142.        
  143.     } else {
  144.        
  145.         if([selector isEqualToString:@"insertNewline:"]) {
  146.             [self stopEditingCommitChanges:TRUE clearFirstResponder:TRUE];
  147.             handlesCommand = TRUE;
  148.         }
  149.        
  150.         if([selector isEqualToString:@"insertTab:"]) {
  151.             [self stopEditingCommitChanges:TRUE clearFirstResponder:FALSE];
  152.             handlesCommand = FALSE;
  153.         }
  154.     }
  155.    
  156.     return handlesCommand;
  157. }
  158.  
  159. @end
Advertisement
Add Comment
Please, Sign In to add comment