// // MPExpressionStorage.m // MathPad // // Created by Kim Wittenburg on 22.04.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #import "MPExpressionStorage.h" #import "MPExpressionLayout.h" #import "MPFunctionLayout.h" #import "MPRangePath.h" @interface MPExpressionStorage () @property (nonatomic, strong) NSLayoutManager *layoutManager; @property (nonatomic, strong) NSTextContainer *textContainer; @property (nonatomic, strong) NSTextStorage *textStorage; @end @implementation MPExpressionStorage - (instancetype)initWithSymbols:(NSArray *)symbols { self = [super initWithSymbols:symbols]; if (self) { _expressionLayout = [[MPExpressionLayout alloc] initRootLayoutWithExpressionStorage:self]; } return self; } - (NSLayoutManager *)layoutManager { [self ensureTextSystemObjects]; return _layoutManager; } - (NSTextContainer *)textContainer { [self ensureTextSystemObjects]; return _textContainer; } - (NSTextStorage *)textStorage { [self ensureTextSystemObjects]; return _textStorage; } - (void)ensureTextSystemObjects { if (_layoutManager == nil || _textContainer == nil || _textStorage == nil) { _textStorage = [[NSTextStorage alloc] init]; NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)]; NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; [layoutManager addTextContainer:textContainer]; [_textStorage addLayoutManager:layoutManager]; _textContainer = textContainer; _layoutManager = layoutManager; } } - (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length { if (rangePath.location.length == 0) { return; } id current = self.expressionLayout; for (NSUInteger position = 1; position < rangePath.location.length-1; position++) { if ([current isKindOfClass:[MPExpressionLayout class]]) { current = [(MPExpressionLayout *)current functionLayoutForFunctionAtIndex:position]; } else { current = [(MPFunctionLayout *)current expressionLayoutForChildAtIndex:position]; } } if ([current isKindOfClass:[MPExpressionLayout class]]) { [(MPExpressionLayout *)current editedExpressionInRange:rangePath.rangeAtLastIndex replacementLength:length]; } else { [(MPFunctionLayout *)current editedChildAtIndex:[rangePath.location indexAtPosition:rangePath.location.length-1]]; } } @end