-
-
Save ioquatix/f8357f895fbefe4ad96a9e71e668dbf3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TTExpressionEditorView.m | |
// Truth Tables | |
// | |
// Created by Samuel Williams on 18/11/11. | |
// Copyright (c) 2011 Orion Transfer Ltd. All rights reserved. | |
// | |
#import "TTExpressionEditorView.h" | |
#import "NSObject+BindingPropagation.h" | |
#import "TTParser.h" | |
#import "TTOperators.h" | |
enum { | |
TTEnterKey = 36 | |
}; | |
@implementation TTExpressionEditorView | |
@synthesize operators = _operators, parser = _parser, expression = _expression; | |
- (void)awakeFromNib | |
{ | |
[self setOperators:[TTOperators standardOperators]]; | |
} | |
- (void) updateExpressionValue:(NSString*)expression into:(NSMutableAttributedString*)buffer | |
{ | |
// For some reason, when using this font, the vertical alignment becomes odd. | |
NSFont * identifierFont = [[NSFontManager sharedFontManager] convertFont:self.font toHaveTrait:NSBoldFontMask]; | |
//NSFont * identifierFont = self.font; | |
NSColor * operatorColor = [NSColor colorWithCalibratedHue:49.0 saturation:0.8 brightness:0.5 alpha:1.0]; | |
if (expression.length > 0) { | |
TTParser * parser = [TTParser parse:expression withOperators:self.operators]; | |
[self setParser:parser]; | |
{ | |
[buffer addAttribute:NSFontAttributeName value:self.font range:(NSRange){0, buffer.length}]; | |
[buffer removeAttribute:NSForegroundColorAttributeName range:(NSRange){0, buffer.length}]; | |
for (TTToken * token in self.parser.expressions) { | |
NSRange textRange = {token.offset, token.text.length}; | |
if ([token isKindOfClass:[TTIdentifierToken class]]) { | |
[buffer addAttribute:NSFontAttributeName value:identifierFont range:textRange]; | |
} | |
if ([token isKindOfClass:[TTOperatorToken class]]) { | |
[buffer addAttribute:NSForegroundColorAttributeName value:operatorColor range:textRange]; | |
} | |
} | |
for (TTParserError * error in self.parser.errors) { | |
TTToken * token = error.token; | |
NSRange textRange = {token.offset, token.text.length}; | |
//NSLog(@"Error at range: %@, %@", NSStringFromRange(textRange), error.message); | |
if (textRange.location >= buffer.length || (textRange.location + textRange.length) > buffer.length) { | |
//NSLog(@"Error out of range: %lu", buffer.length); | |
continue; | |
} | |
[buffer addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:textRange]; | |
} | |
} | |
} else { | |
[self setParser:nil]; | |
} | |
} | |
- (void) updateEditorHighlighting: (NSString*)expression | |
{ | |
NSTextView * editor = (NSTextView*)[self currentEditor]; | |
[self updateExpressionValue:self.stringValue into:editor.textStorage]; | |
} | |
- (void) setExpression:(NSString *)expression | |
{ | |
if (self.expression == expression) | |
return; | |
if (expression && [self.expression isEqualToString:expression]) | |
return; | |
[self willChangeValueForKey:@"expression"]; | |
_expression = expression; | |
if (_expression) { | |
[self setStringValue:_expression]; | |
NSMutableAttributedString * buffer = self.attributedStringValue.mutableCopy; | |
[self updateExpressionValue:_expression into:buffer]; | |
[self setAllowsEditingTextAttributes:YES]; | |
[self setAttributedStringValue:buffer]; | |
[self setAllowsEditingTextAttributes:NO]; | |
} | |
//NSLog(@"Editor updated expression: %@", _expression); | |
[self didChangeValueForKey:@"expression"]; | |
} | |
- (BOOL)becomeFirstResponder | |
{ | |
BOOL result = [super becomeFirstResponder]; | |
[self updateEditorHighlighting:self.stringValue]; | |
return result; | |
} | |
- (void)textDidChange:(NSNotification *)aNotification | |
{ | |
[self updateEditorHighlighting:self.stringValue]; | |
[super textDidChange:aNotification]; | |
} | |
- (void)textDidEndEditing:(NSNotification *)notification | |
{ | |
if (self.parser && self.parser.errors.count == 0) { | |
if (![self.stringValue isEqualToString:self.expression]) { | |
// Update the model | |
[self setExpression:self.stringValue]; | |
// Seems a bit weird...? | |
[self propagateValue:self.stringValue forBinding:@"expression"]; | |
} | |
} | |
// This causes some issues for selection. | |
//[super textDidEndEditing:notification]; | |
} | |
- (BOOL)textShouldEndEditing:(NSText *)textObject | |
{ | |
NSEvent * event = [NSApp currentEvent]; | |
// The user pressed enter. | |
if (event.type == NSKeyDown && event.keyCode == TTEnterKey) { | |
if (self.parser.errors.count != 0) { | |
return NO; | |
} | |
} | |
return YES; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment