diff --git a/MathPad/Base.lproj/MPDocument.xib b/MathPad/Base.lproj/MPDocument.xib index 9783c54..1600811 100644 --- a/MathPad/Base.lproj/MPDocument.xib +++ b/MathPad/Base.lproj/MPDocument.xib @@ -1,5 +1,5 @@ - + @@ -31,6 +31,17 @@ + diff --git a/MathPad/MPDocument.h b/MathPad/MPDocument.h index d510304..927eff2 100644 --- a/MathPad/MPDocument.h +++ b/MathPad/MPDocument.h @@ -13,4 +13,6 @@ @property (weak) IBOutlet MPExpressionView *termExpressionView; @property (weak) IBOutlet MPExpressionView *resultExpressionView; +- (IBAction)changeExpression:(id)sender; + @end diff --git a/MathPad/MPDocument.m b/MathPad/MPDocument.m index c3acc12..6e86a3c 100644 --- a/MathPad/MPDocument.m +++ b/MathPad/MPDocument.m @@ -58,4 +58,10 @@ return YES; } +#pragma mark Actions + +- (IBAction)changeExpression:(id)sender { + [self.resultExpressionView.expressionStorage insertString:@"abc" atIndex:6]; +} + @end diff --git a/MathPad/MPExpressionLayout.h b/MathPad/MPExpressionLayout.h index 4fec051..7c05565 100644 --- a/MathPad/MPExpressionLayout.h +++ b/MathPad/MPExpressionLayout.h @@ -8,7 +8,7 @@ #import -@class MPExpressionLayout, MPFunctionLayout, MPExpressionStorage, MPExpression; +@class MPExpressionLayout, MPFunctionLayout, MPExpressionStorage, MPExpressionView, MPExpression; @interface MPExpressionLayout : NSObject { BOOL _valid; @@ -30,6 +30,8 @@ @property (readonly, nonatomic, weak) MPExpressionStorage *expressionStorage; @property (readonly, nonatomic, strong) NSIndexPath *expressionPath; +@property (nonatomic, weak) MPExpressionView *expressionView; + - (MPExpression *)expression; // Convenience - (NSLayoutManager *)layoutManager; - (NSTextContainer *)textContainer; @@ -38,7 +40,7 @@ #pragma mark Cache Methods - (void)invalidate; -- (void)expressionEditedInRange:(NSRange)range +- (void)editedExpressionInRange:(NSRange)range replacementLength:(NSUInteger)length; - (BOOL)hasCacheForSymbolAtIndex:(NSUInteger)index; diff --git a/MathPad/MPExpressionLayout.m b/MathPad/MPExpressionLayout.m index f5c9c09..6b4da0a 100644 --- a/MathPad/MPExpressionLayout.m +++ b/MathPad/MPExpressionLayout.m @@ -10,6 +10,7 @@ #import "MPExpressionStorage.h" #import "MPFunctionLayout.h" #import "MPModel.h" +#import "MPExpressionView.h" @implementation MPExpressionLayout @@ -71,15 +72,20 @@ #pragma mark Cache Methods +// TODO: Return nil from caching with illegal index + - (void)invalidate { _valid = NO; [self.parent invalidate]; + [self.expressionView setNeedsDisplay:YES]; } -- (void)expressionEditedInRange:(NSRange)range replacementLength:(NSUInteger)length +- (void)editedExpressionInRange:(NSRange)range replacementLength:(NSUInteger)length { - while (_symbolCache.count < self.expression.numberOfSymbols) { + // TODO: New symbols may also be inserted in the middle or at the beginning + NSInteger changeInLength = length - range.length; + while (_symbolCache.count < (self.expression.numberOfSymbols + changeInLength)) { [_symbolCache addObject:[NSNull null]]; } NSMutableArray *newPlaceholders = [[NSMutableArray alloc] initWithCapacity:length]; @@ -101,7 +107,11 @@ - (MPFunctionLayout *)functionLayoutForFunctionAtIndex:(NSUInteger)index; { if ([self hasCacheForSymbolAtIndex:index]) { - return _symbolCache[index]; + id cacheObject = _symbolCache[index]; + if ([cacheObject isKindOfClass:[NSValue class]]) { + return nil; + } + return cacheObject; } MPFunctionLayout *layout = [MPFunctionLayout functionLayoutForFunctionAtIndexPath:[self.expressionPath indexPathByAddingIndex:index] parent:self]; while (index >= _symbolCache.count) { @@ -177,6 +187,8 @@ atPoint:(NSPoint)point { id symbol = [self.expression symbolAtIndex:index]; + // point.x = point.y = 0; + NSLog(@"draw Symbol: %@ at Point: (x: %f, y: %f)", symbol, point.x, point.y); if ([symbol isString]) { [self.textStorage setString:symbol]; NSRange glyphRange = [self.layoutManager glyphRangeForTextContainer:self.textContainer]; @@ -184,6 +196,7 @@ atPoint:point]; } else { MPFunctionLayout *layout = [self functionLayoutForFunctionAtIndex:index]; + NSLog(@"layout: %@, index: %ld", layout, index); [layout drawFunctionAtPoint:point]; } } diff --git a/MathPad/MPExpressionStorage.m b/MathPad/MPExpressionStorage.m index 7254755..ae665e8 100644 --- a/MathPad/MPExpressionStorage.m +++ b/MathPad/MPExpressionStorage.m @@ -8,6 +8,8 @@ #import "MPExpressionStorage.h" #import "MPExpressionLayout.h" +#import "MPFunctionLayout.h" +#import "MPRangePath.h" @interface MPExpressionStorage () @property (nonatomic, strong) NSLayoutManager *layoutManager; @@ -57,4 +59,24 @@ } } +- (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 diff --git a/MathPad/MPExpressionView.h b/MathPad/MPExpressionView.h index b1c1c78..1cc8b70 100644 --- a/MathPad/MPExpressionView.h +++ b/MathPad/MPExpressionView.h @@ -20,7 +20,7 @@ #pragma mark Properties -@property (readonly, nonatomic, copy) MPExpressionStorage *expressionStorage; +@property (readonly, nonatomic, strong) MPExpressionStorage *expressionStorage; - (MPExpressionLayout *)expressionLayout; // Convenience Method @property (nonatomic, getter = isEditable) BOOL editable; diff --git a/MathPad/MPExpressionView.m b/MathPad/MPExpressionView.m index 0897b64..4a37a62 100644 --- a/MathPad/MPExpressionView.m +++ b/MathPad/MPExpressionView.m @@ -14,9 +14,6 @@ #import "MPSumFunction.h" -@interface MPExpressionView () -@end - @implementation MPExpressionView #pragma mark Creation Methods @@ -50,12 +47,20 @@ - (void)initializeObjects { - MPExpressionStorage *expressionStorage = [[MPExpressionStorage alloc] initWithSymbols:@[@"12345", [[MPSumFunction alloc] init]]]; + MPExpressionStorage *expressionStorage = [[MPExpressionStorage alloc] initWithSymbols:@[@"12 345", [[MPSumFunction alloc] init], [[MPSumFunction alloc] init]]]; _expressionStorage = expressionStorage; + [self.expressionLayout setExpressionView:self]; } #pragma mark Properties +- (void)setExpressionStorage:(MPExpressionStorage *)expressionStorage +{ + [_expressionStorage.expressionLayout setExpressionView:nil]; + _expressionStorage = expressionStorage; + [_expressionStorage.expressionLayout setExpressionView:self]; +} + - (MPExpressionLayout *)expressionLayout { return self.expressionStorage.expressionLayout;