2016-03-21 11 views
6

У меня есть компонент, основанный на NSTextView, и я хотел бы отключить отдельные клики на нем, так что его точка вставки не зависит от этих одиночных кликов, но все же, чтобы иметь возможность выбирать фрагменты текста для копирования и вставки:NSTextView: как отключить отдельные клики, но все же разрешить выбор для копирования и вставки?

  1. одиночные щелчки ничего не делать
  2. копирования и вставки можно и не влияет на точку вставки

то, что я хочу, это именно то, что мы имеем в приложение Terminal по умолчанию: есть точка вставки и невозможно изменить его с помощью мыши, но выбор текста для копирования и вставки возможное.

Я пробовал посмотреть на метод - (void)mouseDown:(NSEvent *)theEvent, но ничего не нашел.

+0

Будет ли редактируемые = НЕТ, выбор = YES будет достаточно? или вам нужно что-то другое? вы можете уточнить? – Remizorrr

+0

Этого может быть достаточно с учетом 'insertText: replacementRange:' будет работать с 'editable = NO', но не добавляет никакого текста. –

+0

@StanislavPankevich может быть настроен только для редактирования справа перед вставкой, а затем вернуться к НЕТ? – faviomob

ответ

1

Я нашел хакерское обходное решение для достижения такого рода поведения. Я создал demo project, соответствующий класс TerminalLikeTextView. Это решение работает отлично, но мне все же хотелось бы иметь лучшее решение: менее хакерское и менее зависимое от внутренней механики NSTextView, поэтому, если кто-нибудь имеет такую ​​просьбу, пожалуйста, поделитесь.

Основные шаги:

1) Установить mouseDownFlag Да, прежде чем мышь вниз и НЕТ после того, как:

@property (assign, nonatomic) BOOL mouseDownFlag; 

- (void)mouseDown:(NSEvent *)theEvent { 
    self.mouseDownFlag = YES; 

    [super mouseDown:theEvent]; 

    self.mouseDownFlag = NO; 
} 

2) Для того, чтобы предотвратить точку вставки от обновления возврата раньше от updateInsertionPointStateAndRestartTimer метода:

- (void)updateInsertionPointStateAndRestartTimer:(BOOL)flag { 
    if (self.mouseDownFlag) { 
     return; 
    } 

    [super updateInsertionPointStateAndRestartTimer:flag]; 
} 

3) Первые два шага заставят точку ввода не перемещаться с помощью мыши, однако selectionRange по-прежнему будет изменен, поэтому мы n ПЕД следить за ним:

static const NSUInteger kCursorLocationSnapshotNotExists = NSUIntegerMax; 
@property (assign, nonatomic) NSUInteger cursorLocationSnapshot; 

#pragma mark - <NSTextViewDelegate> 

- (NSRange)textView:(NSTextView *)textView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange { 

    if (self.mouseDownFlag && self.cursorLocationSnapshot == kCursorLocationSnapshotNotExists) { 
     self.cursorLocationSnapshot = oldSelectedCharRange.location; 
    } 

    return newSelectedCharRange; 
} 

4) Попытка печати с помощью клавиш восстанавливает местоположение, если необходимо:

- (void)keyDown:(NSEvent *)event { 
    NSString *characters = event.characters; 

    [self insertTextToCurrentPosition:characters]; 
} 

- (void)insertTextToCurrentPosition:(NSString *)text { 
    if (self.cursorLocationSnapshot != kCursorLocationSnapshotNotExists) { 
     self.selectedRange = NSMakeRange(self.cursorLocationSnapshot, 0); 
     self.cursorLocationSnapshot = kCursorLocationSnapshotNotExists; 
    } 

    [self insertText:text replacementRange:NSMakeRange(self.selectedRange.location, 0)]; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^