diff --git a/MathPad/MPExpression.h b/MathPad/MPExpression.h index 28e3bd3..977470e 100644 --- a/MathPad/MPExpression.h +++ b/MathPad/MPExpression.h @@ -19,6 +19,14 @@ extern NSString *MPDivisionOperator; - (instancetype)initWithSymbols:(NSArray *)symbols; +#pragma mark Working With the Expression Tree + +@property (nonatomic, weak) MPFunction *parent; // Documentation: Do not set, may be nil +- (void)functionSymbolChanged:(MPFunction *)symbol + atLocalIndexPath:(NSIndexPath *)indexPath; // Index path of change in symbol + +- (void)fixSymbols; + #pragma mark Primitive Methods - (NSUInteger)numberOfSymbols; @@ -81,6 +89,9 @@ extern NSString *MPDivisionOperator; - (void)replaceSymbolsInRange:(NSRange)range withSymbols:(NSArray *)symbols; +- (void)beginEditing; +- (void)endEditing; + @end @interface MPMutableExpression (MPMutableExpressionExtensionMethods) diff --git a/MathPad/MPExpression.m b/MathPad/MPExpression.m index bdcb62d..63f9fd6 100644 --- a/MathPad/MPExpression.m +++ b/MathPad/MPExpression.m @@ -21,8 +21,7 @@ NSString *MPDivisionOperator = @"/"; - (NSInteger)lengthOfSymbol:(id)symbol; - (void)validateSymbols:(NSArray *)symbols; -- (NSArray *)repairedSymbols:(NSArray *)symbols; // Merges subsequent strings -- (void)repairSymbols:(NSMutableArray *)symbols; +- (NSArray *)fixedSymbols:(NSArray *)symbols; - (void)getSplitOffset:(out NSUInteger *)offset inSymbolAtIndex:(out NSUInteger *)symbolIndex forSplitLocation:(NSUInteger)loc; @@ -42,13 +41,28 @@ NSString *MPDivisionOperator = @"/"; [self validateSymbols:symbols]; self = [super init]; if (self) { - symbols = [self repairedSymbols:symbols]; _symbols = [[NSArray alloc] initWithArray:symbols copyItems:YES]; + [self fixSymbols]; } return self; } +#pragma mark Working With the Expression Tree + +- (void)functionSymbolChanged:(MPFunction *)symbol atLocalIndexPath:(NSIndexPath *)indexPath +{ + NSUInteger index = [_symbols indexOfObject:symbol]; + if (index != NSNotFound) { + [self.parent childChanged:self atLocalIndexPath:[indexPath indexPathByAddingIndex:index]]; + } +} + +- (void)fixSymbols +{ + _symbols = [self fixedSymbols:_symbols]; +} + #pragma mark Primitive Methods - (NSUInteger)numberOfSymbols @@ -108,7 +122,6 @@ NSString *MPDivisionOperator = @"/"; return 1; } -// TODO: Deal with subsequent strings - (void)validateSymbols:(NSArray *)symbols { for (id symbol in symbols) { @@ -121,31 +134,27 @@ NSString *MPDivisionOperator = @"/"; } } -// TODO: Deal with empty strings -- (NSArray *)repairedSymbols:(NSArray *)symbols +- (NSArray *)fixedSymbols:(NSArray *)symbols { NSMutableArray *mutableSymbols = [symbols mutableCopy]; - [self repairSymbols:mutableSymbols]; - return [mutableSymbols copy]; -} - -- (void)repairSymbols:(NSMutableArray *)symbols -{ - for (NSInteger index = 0; index < symbols.count; index++) { - id next = index+1 < symbols.count ? symbols[index+1] : nil; - id current = symbols[index]; + for (NSInteger index = 0; index < mutableSymbols.count; index++) { + id next = index+1 < mutableSymbols.count ? mutableSymbols[index+1] : nil; + id current = mutableSymbols[index]; if ([current isString]) { if ([current length] == 0) { - [symbols removeObjectAtIndex:index]; + [mutableSymbols removeObjectAtIndex:index]; index--; } else if ([next isString]) { NSString *new = [NSString stringWithFormat:@"%@%@", current, next]; - [symbols replaceObjectAtIndex:index withObject:new]; - [symbols removeObjectAtIndex:index+1]; + [mutableSymbols replaceObjectAtIndex:index withObject:new]; + [mutableSymbols removeObjectAtIndex:index+1]; index--; } + } else { + [(MPFunction *)current setParent:self]; } } + return [mutableSymbols copy]; } - (void)getSplitOffset:(out NSUInteger *)offset @@ -396,20 +405,28 @@ NSString *MPDivisionOperator = @"/"; @end -@implementation MPMutableExpression +@implementation MPMutableExpression { + @protected + NSInteger _editCount; +} - (instancetype)initWithSymbols:(NSArray *)symbols { [self validateSymbols:symbols]; self = [super initWithSymbols:nil]; if (self) { - symbols = [self repairedSymbols:symbols]; _symbols = [[NSMutableArray alloc] initWithArray:symbols copyItems:YES]; + [self fixSymbols]; } return self; } +- (void)fixSymbols +{ + _symbols = [[self fixedSymbols:_symbols] mutableCopy]; +} + - (NSArray *)symbols { // Return an immutable array: @@ -451,7 +468,9 @@ NSString *MPDivisionOperator = @"/"; } // Revalidate structure and invalidate length - [self repairSymbols:(NSMutableArray *)_symbols]; + if (_editCount == 0) { + [self fixSymbols]; + } _length = 0; } @@ -481,6 +500,22 @@ NSString *MPDivisionOperator = @"/"; *insertionIndex = splitSymbolIndex; } +- (void)beginEditing +{ + _editCount++; +} + +- (void)endEditing +{ + if (_editCount == 0) { + return; + } + _editCount--; + if (_editCount == 0) { + [self fixSymbols]; + } +} + @end @implementation MPMutableExpression (MPMutableExpressionExtensionMethods) diff --git a/MathPad/MPFunction.h b/MathPad/MPFunction.h index 8e2bafa..dc3b7b0 100644 --- a/MathPad/MPFunction.h +++ b/MathPad/MPFunction.h @@ -14,7 +14,11 @@ - (instancetype)init; -#pragma mark Children +#pragma mark Working With the Expression Tree + +@property (nonatomic, weak) MPExpression *parent; // Documentation: Do not set +- (void)childChanged:(MPExpression *)child + atLocalIndexPath:(NSIndexPath *)indexPath; - (NSUInteger)numberOfChildren; - (MPExpression *)childAtIndex:(NSUInteger)index; diff --git a/MathPad/MPFunction.m b/MathPad/MPFunction.m index a1aa526..6c6e2aa 100644 --- a/MathPad/MPFunction.m +++ b/MathPad/MPFunction.m @@ -7,6 +7,7 @@ // #import "MPFunction.h" +#import "MPExpression.h" @implementation MPFunction @@ -20,7 +21,13 @@ return self; } -#pragma mark Children +#pragma mark Working With the Expression Tree + +- (void)childChanged:(MPExpression *)child atLocalIndexPath:(NSIndexPath *)indexPath +{ + [self.parent functionSymbolChanged:self + atLocalIndexPath:[indexPath indexPathByAddingIndex:0]]; +} - (NSUInteger)numberOfChildren { diff --git a/MathPad/NSObject+MPStringTest.h b/MathPad/NSObject+MPStringTest.h new file mode 100644 index 0000000..73081d5 --- /dev/null +++ b/MathPad/NSObject+MPStringTest.h @@ -0,0 +1,15 @@ +// +// NSObject+MPStringTest.h +// MathPad +// +// Created by Kim Wittenburg on 20.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import + +@interface NSObject (MPStringTest) + +- (BOOL)isString; + +@end diff --git a/MathPad/NSObject+MPStringTest.m b/MathPad/NSObject+MPStringTest.m new file mode 100644 index 0000000..6a3fe2f --- /dev/null +++ b/MathPad/NSObject+MPStringTest.m @@ -0,0 +1,18 @@ +// +// NSObject+MPStringTest.m +// MathPad +// +// Created by Kim Wittenburg on 20.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import "NSObject+MPStringTest.h" + +@implementation NSObject (MPStringTest) + +- (BOOL)isString +{ + return [self isKindOfClass:[NSString class]]; +} + +@end