Archived
1

Added Change Notifications to MPExpression, MPMutableExpression and MPFunction

Removed -beginEditing and -endEditing
Optimized -fixSymbols
Updated Project File
This commit is contained in:
Kim Wittenburg
2014-05-18 01:06:49 +02:00
parent fa499d299c
commit 982b70d7fb
5 changed files with 119 additions and 65 deletions

View File

@@ -26,7 +26,6 @@
3BBBA35E1903FD3600824E74 /* MPRangePath.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B87E35C1900933200259938 /* MPRangePath.m */; }; 3BBBA35E1903FD3600824E74 /* MPRangePath.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B87E35C1900933200259938 /* MPRangePath.m */; };
3BBBA35F1903FD3600824E74 /* 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 */; }; 3BBBA3951905704200824E74 /* MPRangeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BBBA3941905704200824E74 /* MPRangeTests.m */; };
3BEB0F8119074815005699AB /* MPDisplayExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BEB0F8019074815005699AB /* MPDisplayExtension.m */; };
3BF9976F18DE623E009CF6C4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BF9976E18DE623E009CF6C4 /* Cocoa.framework */; }; 3BF9976F18DE623E009CF6C4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BF9976E18DE623E009CF6C4 /* Cocoa.framework */; };
3BF9977918DE623E009CF6C4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3BF9977718DE623E009CF6C4 /* InfoPlist.strings */; }; 3BF9977918DE623E009CF6C4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3BF9977718DE623E009CF6C4 /* InfoPlist.strings */; };
3BF9977B18DE623E009CF6C4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BF9977A18DE623E009CF6C4 /* main.m */; }; 3BF9977B18DE623E009CF6C4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BF9977A18DE623E009CF6C4 /* main.m */; };
@@ -81,8 +80,6 @@
3BBBA35C1903F8A700824E74 /* NSObject+MPStringTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MPStringTest.m"; sourceTree = "<group>"; }; 3BBBA35C1903F8A700824E74 /* NSObject+MPStringTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MPStringTest.m"; sourceTree = "<group>"; };
3BBBA38419047FC900824E74 /* MPView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPView.h; sourceTree = "<group>"; }; 3BBBA38419047FC900824E74 /* MPView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPView.h; sourceTree = "<group>"; };
3BBBA3941905704200824E74 /* MPRangeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPRangeTests.m; sourceTree = "<group>"; }; 3BBBA3941905704200824E74 /* MPRangeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPRangeTests.m; sourceTree = "<group>"; };
3BEB0F7F19074815005699AB /* MPDisplayExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDisplayExtension.h; sourceTree = "<group>"; };
3BEB0F8019074815005699AB /* MPDisplayExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDisplayExtension.m; sourceTree = "<group>"; };
3BF9976B18DE623E009CF6C4 /* MathPad.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MathPad.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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; }; 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; }; 3BF9977118DE623E009CF6C4 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -190,8 +187,6 @@
3BB09ED419071A140080A5ED /* Categories */ = { 3BB09ED419071A140080A5ED /* Categories */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3BEB0F7F19074815005699AB /* MPDisplayExtension.h */,
3BEB0F8019074815005699AB /* MPDisplayExtension.m */,
); );
name = Categories; name = Categories;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -415,7 +410,6 @@
files = ( files = (
3BB09EE1190736160080A5ED /* MPSumFunctionLayout.m in Sources */, 3BB09EE1190736160080A5ED /* MPSumFunctionLayout.m in Sources */,
3B87E3561900856F00259938 /* MPExpressionView.m in Sources */, 3B87E3561900856F00259938 /* MPExpressionView.m in Sources */,
3BEB0F8119074815005699AB /* MPDisplayExtension.m in Sources */,
3BFCFF491905AAF30001FE33 /* NSTextStorage+MPSetContents.m in Sources */, 3BFCFF491905AAF30001FE33 /* NSTextStorage+MPSetContents.m in Sources */,
3BB09EC91906FD830080A5ED /* MPSumFunction.m in Sources */, 3BB09EC91906FD830080A5ED /* MPSumFunction.m in Sources */,
3BB09EB21905DE500080A5ED /* MPExpressionStorage.m in Sources */, 3BB09EB21905DE500080A5ED /* MPExpressionStorage.m in Sources */,

View File

@@ -6,7 +6,7 @@
// Copyright (c) 2014 Kim Wittenburg. All rights reserved. // Copyright (c) 2014 Kim Wittenburg. All rights reserved.
// //
@class MPExpression, MPFunction; @class MPExpression, MPFunction, MPRangePath;
extern NSString *MPAdditionOperator; extern NSString *MPAdditionOperator;
extern NSString *MPSubtractionOperator; extern NSString *MPSubtractionOperator;
@@ -86,14 +86,17 @@ extern NSString *MPDivisionOperator;
@end @end
@interface MPExpression (MPChangeNotificationExtension)
- (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length;
@end
@interface MPMutableExpression : MPExpression @interface MPMutableExpression : MPExpression
- (void)replaceSymbolsInRange:(NSRange)range - (void)replaceSymbolsInRange:(NSRange)range
withSymbols:(NSArray *)symbols; withSymbols:(NSArray *)symbols;
- (void)beginEditing;
- (void)endEditing;
@end @end
@interface MPMutableExpression (MPMutableExpressionExtensionMethods) @interface MPMutableExpression (MPMutableExpressionExtensionMethods)

View File

@@ -9,9 +9,10 @@
#import "MPExpression.h" #import "MPExpression.h"
#import "MPFunction.h" #import "MPFunction.h"
#import "MPException.h" #import "MPException.h"
#import "MPRangePath.h"
#import "NSObject+MPStringTest.h" #import "NSObject+MPStringTest.h"
#import "NSIndexPath+MPRemoveFirstIndex.h" #import "NSIndexPath+MPReverseIndexPath.h"
NSString *MPAdditionOperator = @"+"; NSString *MPAdditionOperator = @"+";
NSString *MPSubtractionOperator = @"-"; NSString *MPSubtractionOperator = @"-";
@@ -22,7 +23,6 @@ NSString *MPDivisionOperator = @"/";
- (NSInteger)lengthOfSymbol:(id)symbol; - (NSInteger)lengthOfSymbol:(id)symbol;
- (void)validateSymbols:(NSArray *)symbols; - (void)validateSymbols:(NSArray *)symbols;
- (NSArray *)fixedSymbols:(NSArray *)symbols;
- (void)getSplitOffset:(out NSUInteger *)offset - (void)getSplitOffset:(out NSUInteger *)offset
inSymbolAtIndex:(out NSUInteger *)symbolIndex inSymbolAtIndex:(out NSUInteger *)symbolIndex
forSplitLocation:(NSUInteger)loc; forSplitLocation:(NSUInteger)loc;
@@ -53,7 +53,25 @@ NSString *MPDivisionOperator = @"/";
- (void)fixSymbols - (void)fixSymbols
{ {
_symbols = [self fixedSymbols:_symbols]; NSMutableArray *mutableSymbols = [_symbols mutableCopy];
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) {
[mutableSymbols removeObjectAtIndex:index];
index--;
} else if ([next isString]) {
NSString *new = [NSString stringWithFormat:@"%@%@", current, next];
[mutableSymbols replaceObjectAtIndex:index withObject:new];
[mutableSymbols removeObjectAtIndex:index+1];
index--;
}
} else {
[(MPFunction *)current setParent:self];
}
}
_symbols = [mutableSymbols copy];
} }
#pragma mark Primitive Methods #pragma mark Primitive Methods
@@ -127,29 +145,6 @@ NSString *MPDivisionOperator = @"/";
} }
} }
- (NSArray *)fixedSymbols:(NSArray *)symbols
{
NSMutableArray *mutableSymbols = [symbols mutableCopy];
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) {
[mutableSymbols removeObjectAtIndex:index];
index--;
} else if ([next isString]) {
NSString *new = [NSString stringWithFormat:@"%@%@", current, next];
[mutableSymbols replaceObjectAtIndex:index withObject:new];
[mutableSymbols removeObjectAtIndex:index+1];
index--;
}
} else {
[(MPFunction *)current setParent:self];
}
}
return [mutableSymbols copy];
}
- (void)getSplitOffset:(out NSUInteger *)offset - (void)getSplitOffset:(out NSUInteger *)offset
inSymbolAtIndex:(out NSUInteger *)symbolIndex inSymbolAtIndex:(out NSUInteger *)symbolIndex
forSplitLocation:(NSUInteger)loc forSplitLocation:(NSUInteger)loc
@@ -420,9 +415,24 @@ NSString *MPDivisionOperator = @"/";
@end @end
@implementation MPExpression (MPChangeNotificationExtension)
- (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length
{
if (!self.parent) {
return;
}
NSUInteger selfIndex = [self.parent indexOfChild:self];
NSIndexPath *newLocation = [rangePath.location indexPathByPrecedingIndex:selfIndex];
MPRangePath *newPath = [[MPRangePath alloc] initWithLocation:newLocation length:rangePath.length];
[self.parent symbolsChangedInRangePath:newPath replacementLength:length];
}
@end
@implementation MPMutableExpression { @implementation MPMutableExpression {
@protected NSRange editedRange;
NSInteger _editCount; NSRange replacementRange;
} }
- (instancetype)initWithSymbols:(NSArray *)symbols - (instancetype)initWithSymbols:(NSArray *)symbols
@@ -430,6 +440,8 @@ NSString *MPDivisionOperator = @"/";
[self validateSymbols:symbols]; [self validateSymbols:symbols];
self = [super initWithSymbols:nil]; self = [super initWithSymbols:nil];
if (self) { if (self) {
editedRange = NSMakeRange(0, 0);
replacementRange = NSMakeRange(0, 0);
_symbols = [[NSMutableArray alloc] initWithArray:symbols _symbols = [[NSMutableArray alloc] initWithArray:symbols
copyItems:YES]; copyItems:YES];
[self fixSymbols]; [self fixSymbols];
@@ -439,7 +451,38 @@ NSString *MPDivisionOperator = @"/";
- (void)fixSymbols - (void)fixSymbols
{ {
_symbols = [[self fixedSymbols:_symbols] mutableCopy]; NSMutableArray *mutableSymbols = (NSMutableArray *)_symbols;
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) {
[mutableSymbols removeObjectAtIndex:index];
if (index < replacementRange.location) {
replacementRange.location--;
} else if (index < NSMaxRange(replacementRange)-1) {
replacementRange.length--;
} else if (index == NSMaxRange(replacementRange)) {
editedRange.length++;
}
index--;
} else if ([next isString]) {
NSString *new = [NSString stringWithFormat:@"%@%@", current, next];
[mutableSymbols replaceObjectAtIndex:index withObject:new];
[mutableSymbols removeObjectAtIndex:index+1];
if (index < replacementRange.location) {
replacementRange.location--;
} else if (index < NSMaxRange(replacementRange)-1) {
replacementRange.length--;
} else if (index == NSMaxRange(replacementRange)-1) {
editedRange.length++;
}
index--;
}
} else {
[(MPFunction *)current setParent:self];
}
}
} }
- (NSArray *)symbols - (NSArray *)symbols
@@ -460,22 +503,27 @@ NSString *MPDivisionOperator = @"/";
// Locate the position, split the symbols // Locate the position, split the symbols
NSUInteger startIndex; NSUInteger startIndex;
BOOL didSplitStart = NO;
if ([self numberOfSymbols] == 0) { if ([self numberOfSymbols] == 0) {
startIndex = 0; startIndex = 0;
} else { } else {
[self splitSymbolsAtLocation:range.location [self splitSymbolsAtLocation:range.location
insertionIndex:&startIndex]; insertionIndex:&startIndex
didSplit:&didSplitStart];
} }
// Perform the deletion // Perform the deletion
NSUInteger endIndex;
BOOL didSplitEnd = NO;
[self splitSymbolsAtLocation:NSMaxRange(range)
insertionIndex:&endIndex
didSplit:&didSplitEnd];
if (range.length > 0) { if (range.length > 0) {
NSUInteger endIndex;
[self splitSymbolsAtLocation:NSMaxRange(range)
insertionIndex:&endIndex];
NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init]; NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init];
for (NSUInteger index = startIndex; index < endIndex; index++) { for (NSUInteger index = startIndex; index < endIndex; index++) {
[indexes addIndex:index]; [indexes addIndex:index];
} }
// TODO: Replace with removeObjectsInRange:
[(NSMutableArray *)_symbols removeObjectsAtIndexes:indexes]; [(NSMutableArray *)_symbols removeObjectsAtIndexes:indexes];
} }
@@ -486,15 +534,20 @@ NSString *MPDivisionOperator = @"/";
withObjectsFromArray:newSymbols]; withObjectsFromArray:newSymbols];
} }
// Revalidate structure and invalidate length // Invalidate length and revalidate structure
if (_editCount == 0) {
[self fixSymbols];
}
_length = 0; _length = 0;
NSUInteger editingStart = startIndex - (didSplitStart?1:0);
NSUInteger editingLength = endIndex - startIndex + (didSplitStart?1:0) + (didSplitEnd?1:0);
editedRange = NSMakeRange(editingStart, editingLength);
replacementRange = NSMakeRange(startIndex, symbols.count);
[self fixSymbols];
MPRangePath *changePath = [[MPRangePath alloc] initWithRange:editedRange];
[self symbolsChangedInRangePath:changePath replacementLength:replacementRange.length];
} }
- (void)splitSymbolsAtLocation:(NSUInteger)loc - (void)splitSymbolsAtLocation:(NSUInteger)loc
insertionIndex:(out NSUInteger *)insertionIndex insertionIndex:(out NSUInteger *)insertionIndex
didSplit:(out BOOL *)flag;
{ {
NSUInteger splitSymbolIndex; NSUInteger splitSymbolIndex;
NSUInteger splitOffset; NSUInteger splitOffset;
@@ -516,25 +569,10 @@ NSString *MPDivisionOperator = @"/";
[(NSMutableArray *)_symbols insertObject:rightPart [(NSMutableArray *)_symbols insertObject:rightPart
atIndex:splitSymbolIndex]; atIndex:splitSymbolIndex];
} }
*flag = splitOffset != 0;
*insertionIndex = splitSymbolIndex; *insertionIndex = splitSymbolIndex;
} }
- (void)beginEditing
{
_editCount++;
}
- (void)endEditing
{
if (_editCount == 0) {
return;
}
_editCount--;
if (_editCount == 0) {
[self fixSymbols];
}
}
@end @end
@implementation MPMutableExpression (MPMutableExpressionExtensionMethods) @implementation MPMutableExpression (MPMutableExpressionExtensionMethods)

View File

@@ -6,7 +6,7 @@
// Copyright (c) 2014 Kim Wittenburg. All rights reserved. // Copyright (c) 2014 Kim Wittenburg. All rights reserved.
// //
@class MPFunction, MPExpression; @class MPFunction, MPExpression, MPRangePath;
@interface MPFunction : NSObject <NSCopying, NSCoding> @interface MPFunction : NSObject <NSCopying, NSCoding>
@@ -55,3 +55,9 @@
- (NSUInteger)hash; - (NSUInteger)hash;
@end @end
@interface MPFunction (MPDisplayExtension)
- (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length;
@end

View File

@@ -8,8 +8,9 @@
#import "MPFunction.h" #import "MPFunction.h"
#import "MPExpression.h" #import "MPExpression.h"
#import "MPRangePath.h"
#import "NSIndexPath+MPRemoveFirstIndex.h" #import "NSIndexPath+MPReverseIndexPath.h"
@implementation MPFunction @implementation MPFunction
@@ -157,3 +158,15 @@
} }
@end @end
@implementation MPFunction (MPDisplayExtension)
- (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length
{
NSUInteger index = [self.parent indexOfSymbol:self];
NSIndexPath *newLocation = [rangePath.location indexPathByPrecedingIndex:index];
MPRangePath *newRangePath = [[MPRangePath alloc] initWithLocation:newLocation length:rangePath.length];
[self.parent symbolsChangedInRangePath:newRangePath replacementLength:length];
}
@end