diff --git a/MathPad.xcodeproj/project.pbxproj b/MathPad.xcodeproj/project.pbxproj index 4585ca5..e331591 100644 --- a/MathPad.xcodeproj/project.pbxproj +++ b/MathPad.xcodeproj/project.pbxproj @@ -19,14 +19,14 @@ 3BB09EC91906FD830080A5ED /* MPSumFunction.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BB09EC81906FD830080A5ED /* MPSumFunction.m */; }; 3BB09ED0190713F00080A5ED /* MPExpressionLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BB09ECF190713F00080A5ED /* MPExpressionLayout.m */; }; 3BB09ED3190713FC0080A5ED /* MPFunctionLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BB09ED2190713FC0080A5ED /* MPFunctionLayout.m */; }; - 3BB09EDE190728220080A5ED /* NSIndexPath+MPRemoveFirstIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BB09EDD190728220080A5ED /* NSIndexPath+MPRemoveFirstIndex.m */; }; + 3BB09EDE190728220080A5ED /* NSIndexPath+MPReverseIndexPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BB09EDD190728220080A5ED /* NSIndexPath+MPReverseIndexPath.m */; }; 3BB09EE1190736160080A5ED /* MPSumFunctionLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BB09EE0190736160080A5ED /* MPSumFunctionLayout.m */; }; 3BBBA358190327B700824E74 /* MPMutableExpressionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBBA357190327B700824E74 /* MPMutableExpressionTests.m */; }; 3BBBA35D1903F8A700824E74 /* NSObject+MPStringTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBBA35C1903F8A700824E74 /* NSObject+MPStringTest.m */; }; 3BBBA35E1903FD3600824E74 /* MPRangePath.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B87E35C1900933200259938 /* MPRangePath.m */; }; 3BBBA35F1903FD3600824E74 /* MPRangePath.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B87E35C1900933200259938 /* MPRangePath.m */; }; 3BBBA3951905704200824E74 /* MPRangeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBBA3941905704200824E74 /* MPRangeTests.m */; }; - 3BEB0F8119074815005699AB /* MPExpression+MPDisplayExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BEB0F8019074815005699AB /* MPExpression+MPDisplayExtension.m */; }; + 3BEB0F8119074815005699AB /* MPDisplayExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BEB0F8019074815005699AB /* MPDisplayExtension.m */; }; 3BF9976F18DE623E009CF6C4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BF9976E18DE623E009CF6C4 /* Cocoa.framework */; }; 3BF9977918DE623E009CF6C4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3BF9977718DE623E009CF6C4 /* InfoPlist.strings */; }; 3BF9977B18DE623E009CF6C4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BF9977A18DE623E009CF6C4 /* main.m */; }; @@ -71,8 +71,8 @@ 3BB09ECF190713F00080A5ED /* MPExpressionLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPExpressionLayout.m; sourceTree = ""; }; 3BB09ED1190713FC0080A5ED /* MPFunctionLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPFunctionLayout.h; sourceTree = ""; }; 3BB09ED2190713FC0080A5ED /* MPFunctionLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFunctionLayout.m; sourceTree = ""; }; - 3BB09EDC190728220080A5ED /* NSIndexPath+MPRemoveFirstIndex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexPath+MPRemoveFirstIndex.h"; sourceTree = ""; }; - 3BB09EDD190728220080A5ED /* NSIndexPath+MPRemoveFirstIndex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexPath+MPRemoveFirstIndex.m"; sourceTree = ""; }; + 3BB09EDC190728220080A5ED /* NSIndexPath+MPReverseIndexPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexPath+MPReverseIndexPath.h"; sourceTree = ""; }; + 3BB09EDD190728220080A5ED /* NSIndexPath+MPReverseIndexPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexPath+MPReverseIndexPath.m"; sourceTree = ""; }; 3BB09EDF190736160080A5ED /* MPSumFunctionLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSumFunctionLayout.h; sourceTree = ""; }; 3BB09EE0190736160080A5ED /* MPSumFunctionLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSumFunctionLayout.m; sourceTree = ""; }; 3BBBA357190327B700824E74 /* MPMutableExpressionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPMutableExpressionTests.m; sourceTree = ""; }; @@ -81,8 +81,8 @@ 3BBBA35C1903F8A700824E74 /* NSObject+MPStringTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MPStringTest.m"; sourceTree = ""; }; 3BBBA38419047FC900824E74 /* MPView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPView.h; sourceTree = ""; }; 3BBBA3941905704200824E74 /* MPRangeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPRangeTests.m; sourceTree = ""; }; - 3BEB0F7F19074815005699AB /* MPExpression+MPDisplayExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPExpression+MPDisplayExtension.h"; sourceTree = ""; }; - 3BEB0F8019074815005699AB /* MPExpression+MPDisplayExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPExpression+MPDisplayExtension.m"; sourceTree = ""; }; + 3BEB0F7F19074815005699AB /* MPDisplayExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDisplayExtension.h; sourceTree = ""; }; + 3BEB0F8019074815005699AB /* MPDisplayExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDisplayExtension.m; sourceTree = ""; }; 3BF9976B18DE623E009CF6C4 /* MathPad.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MathPad.app; sourceTree = BUILT_PRODUCTS_DIR; }; 3BF9976E18DE623E009CF6C4 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 3BF9977118DE623E009CF6C4 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; @@ -190,8 +190,8 @@ 3BB09ED419071A140080A5ED /* Categories */ = { isa = PBXGroup; children = ( - 3BEB0F7F19074815005699AB /* MPExpression+MPDisplayExtension.h */, - 3BEB0F8019074815005699AB /* MPExpression+MPDisplayExtension.m */, + 3BEB0F7F19074815005699AB /* MPDisplayExtension.h */, + 3BEB0F8019074815005699AB /* MPDisplayExtension.m */, ); name = Categories; sourceTree = ""; @@ -223,8 +223,8 @@ 3BBBA35C1903F8A700824E74 /* NSObject+MPStringTest.m */, 3BFCFF471905AAF30001FE33 /* NSTextStorage+MPSetContents.h */, 3BFCFF481905AAF30001FE33 /* NSTextStorage+MPSetContents.m */, - 3BB09EDC190728220080A5ED /* NSIndexPath+MPRemoveFirstIndex.h */, - 3BB09EDD190728220080A5ED /* NSIndexPath+MPRemoveFirstIndex.m */, + 3BB09EDC190728220080A5ED /* NSIndexPath+MPReverseIndexPath.h */, + 3BB09EDD190728220080A5ED /* NSIndexPath+MPReverseIndexPath.m */, ); name = Categories; sourceTree = ""; @@ -415,7 +415,7 @@ files = ( 3BB09EE1190736160080A5ED /* MPSumFunctionLayout.m in Sources */, 3B87E3561900856F00259938 /* MPExpressionView.m in Sources */, - 3BEB0F8119074815005699AB /* MPExpression+MPDisplayExtension.m in Sources */, + 3BEB0F8119074815005699AB /* MPDisplayExtension.m in Sources */, 3BFCFF491905AAF30001FE33 /* NSTextStorage+MPSetContents.m in Sources */, 3BB09EC91906FD830080A5ED /* MPSumFunction.m in Sources */, 3BB09EB21905DE500080A5ED /* MPExpressionStorage.m in Sources */, @@ -424,7 +424,7 @@ 3BB09ED3190713FC0080A5ED /* MPFunctionLayout.m in Sources */, 3BB09ED0190713F00080A5ED /* MPExpressionLayout.m in Sources */, 3BBBA35D1903F8A700824E74 /* NSObject+MPStringTest.m in Sources */, - 3BB09EDE190728220080A5ED /* NSIndexPath+MPRemoveFirstIndex.m in Sources */, + 3BB09EDE190728220080A5ED /* NSIndexPath+MPReverseIndexPath.m in Sources */, 3B87E36019009D5F00259938 /* MPFunction.m in Sources */, 3B0F69A919028C6000817707 /* MPException.m in Sources */, 3BBBA35E1903FD3600824E74 /* MPRangePath.m in Sources */, diff --git a/MathPad/MPDisplayExtension.h b/MathPad/MPDisplayExtension.h new file mode 100644 index 0000000..07d18a9 --- /dev/null +++ b/MathPad/MPDisplayExtension.h @@ -0,0 +1,21 @@ +// +// MPExpression+MPDisplayExtension.h +// MathPad +// +// Created by Kim Wittenburg on 23.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import "MPModel.h" + +@interface MPExpression (MPDisplayExtension) + +- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath; + +@end + +@interface MPFunction (MPDisplayExtension) + +- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath; + +@end diff --git a/MathPad/MPDisplayExtension.m b/MathPad/MPDisplayExtension.m new file mode 100644 index 0000000..599fdcc --- /dev/null +++ b/MathPad/MPDisplayExtension.m @@ -0,0 +1,33 @@ +// +// MPExpression+MPDisplayExtension.m +// MathPad +// +// Created by Kim Wittenburg on 23.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import "MPDisplayExtension.h" + +@implementation MPExpression (MPDisplayExtension) + +- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath +{ + NSUInteger index = [self.parent indexOfChild:self]; + NSIndexPath *newLocation = [rangePath.location indexPathByPrecedingIndex:index]; + [self.parent subexpressionChangedAtRangePath:[[MPRangePath alloc] initWithLocation:newLocation + length:rangePath.length]]; +} + +@end + +@implementation MPFunction (MPDisplayExtension) + +- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath +{ + NSUInteger index = [self.parent indexOfSymbol:self]; + NSIndexPath *newLocation = [rangePath.location indexPathByPrecedingIndex:index]; + [self.parent subexpressionChangedAtRangePath:[[MPRangePath alloc] initWithLocation:newLocation + length:rangePath.length]]; +} + +@end diff --git a/MathPad/MPExpressionLayout.m b/MathPad/MPExpressionLayout.m index 387fa35..f5c9c09 100644 --- a/MathPad/MPExpressionLayout.m +++ b/MathPad/MPExpressionLayout.m @@ -74,6 +74,7 @@ - (void)invalidate { _valid = NO; + [self.parent invalidate]; } - (void)expressionEditedInRange:(NSRange)range replacementLength:(NSUInteger)length @@ -86,7 +87,7 @@ [newPlaceholders addObject:[NSNull null]]; } [_symbolCache replaceObjectsInRange:range withObjectsFromArray:newPlaceholders]; - _valid = NO; + [self invalidate]; } - (BOOL)hasCacheForSymbolAtIndex:(NSUInteger)index diff --git a/MathPad/MPFunctionLayout.h b/MathPad/MPFunctionLayout.h index 0de16a3..5810e71 100644 --- a/MathPad/MPFunctionLayout.h +++ b/MathPad/MPFunctionLayout.h @@ -40,6 +40,7 @@ #pragma mark Cache Methods - (void)invalidate; +- (void)editedChildAtIndex:(NSUInteger)index; - (BOOL)hasCacheForChildAtIndex:(NSUInteger)index; - (MPExpressionLayout *)expressionLayoutForChildAtIndex:(NSUInteger)index; diff --git a/MathPad/MPFunctionLayout.m b/MathPad/MPFunctionLayout.m index 6b98f49..b85a2f5 100644 --- a/MathPad/MPFunctionLayout.m +++ b/MathPad/MPFunctionLayout.m @@ -73,6 +73,15 @@ - (void)invalidate { _valid = NO; + [self.parent invalidate]; +} + +- (void)editedChildAtIndex:(NSUInteger)index +{ + if ([self hasCacheForChildAtIndex:index]) { + _childCache[index] = [NSNull null]; + } + [self invalidate]; } - (BOOL)hasCacheForChildAtIndex:(NSUInteger)index diff --git a/MathPad/MPModel.h b/MathPad/MPModel.h index 26f0e75..df2e393 100644 --- a/MathPad/MPModel.h +++ b/MathPad/MPModel.h @@ -16,9 +16,10 @@ #import "MPException.h" #import "MPExpression.h" #import "MPFunction.h" +#import "MPRangePath.h" #import "NSObject+MPStringTest.h" #import "NSTextStorage+MPSetContents.h" -#import "NSIndexPath+MPRemoveFirstIndex.h" +#import "NSIndexPath+MPReverseIndexPath.h" #endif diff --git a/MathPad/NSIndexPath+MPReverseIndexPath.h b/MathPad/NSIndexPath+MPReverseIndexPath.h new file mode 100644 index 0000000..b9bc20e --- /dev/null +++ b/MathPad/NSIndexPath+MPReverseIndexPath.h @@ -0,0 +1,23 @@ +// +// NSIndexPath+MPRemoveFirstIndex.h +// MathPad +// +// Created by Kim Wittenburg on 23.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import + +@interface NSIndexPath (MPReverseIndexPath) + +/*! + @method indexPathByRemovingFirstIndex + @brief Provides an index path with the indexes in the receiving index path, excluding the first one. + @discussion Returns an empty NSIndexPath instance if the receiving index path’s length is 1 or less. + @return New index path with the receiving index path’s indexes, excluding the first one. + */ +- (NSIndexPath *)indexPathByRemovingFirstIndex; + +- (NSIndexPath *)indexPathByPrecedingIndex:(NSUInteger)index; + +@end diff --git a/MathPad/NSIndexPath+MPReverseIndexPath.m b/MathPad/NSIndexPath+MPReverseIndexPath.m new file mode 100644 index 0000000..b04fd86 --- /dev/null +++ b/MathPad/NSIndexPath+MPReverseIndexPath.m @@ -0,0 +1,37 @@ +// +// NSIndexPath+MPRemoveFirstIndex.m +// MathPad +// +// Created by Kim Wittenburg on 23.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import "NSIndexPath+MPReverseIndexPath.h" + +@implementation NSIndexPath (MPReverseIndexPath) + +- (NSIndexPath *)indexPathByRemovingFirstIndex +{ + if (self.length <= 1) { + return [[NSIndexPath alloc] init]; + } + NSUInteger indexes[self.length]; + [self getIndexes:indexes]; + NSUInteger newIndexes[self.length-1]; + for (NSUInteger i = 0; i < self.length-1; i++) { + newIndexes[i] = indexes[i+1]; + } + return [[NSIndexPath alloc] initWithIndexes:newIndexes length:self.length-1]; +} + +- (NSIndexPath *)indexPathByPrecedingIndex:(NSUInteger)index +{ + NSUInteger newIndexes[self.length+1]; + newIndexes[0] = index; + for (NSUInteger i = 0; i < self.length; i++) { + newIndexes[i+1] = [self indexAtPosition:i]; + } + return [[NSIndexPath alloc] initWithIndexes:newIndexes length:self.length+1]; +} + +@end