Added Change Notifications to MPExpression, MPMutableExpression and MPFunction
Removed -beginEditing and -endEditing Optimized -fixSymbols Updated Project File
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
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 /* 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 */; };
|
||||
@@ -81,8 +80,6 @@
|
||||
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>"; };
|
||||
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; };
|
||||
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 +187,6 @@
|
||||
3BB09ED419071A140080A5ED /* Categories */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3BEB0F7F19074815005699AB /* MPDisplayExtension.h */,
|
||||
3BEB0F8019074815005699AB /* MPDisplayExtension.m */,
|
||||
);
|
||||
name = Categories;
|
||||
sourceTree = "<group>";
|
||||
@@ -415,7 +410,6 @@
|
||||
files = (
|
||||
3BB09EE1190736160080A5ED /* MPSumFunctionLayout.m in Sources */,
|
||||
3B87E3561900856F00259938 /* MPExpressionView.m in Sources */,
|
||||
3BEB0F8119074815005699AB /* MPDisplayExtension.m in Sources */,
|
||||
3BFCFF491905AAF30001FE33 /* NSTextStorage+MPSetContents.m in Sources */,
|
||||
3BB09EC91906FD830080A5ED /* MPSumFunction.m in Sources */,
|
||||
3BB09EB21905DE500080A5ED /* MPExpressionStorage.m in Sources */,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||
//
|
||||
|
||||
@class MPExpression, MPFunction;
|
||||
@class MPExpression, MPFunction, MPRangePath;
|
||||
|
||||
extern NSString *MPAdditionOperator;
|
||||
extern NSString *MPSubtractionOperator;
|
||||
@@ -86,14 +86,17 @@ extern NSString *MPDivisionOperator;
|
||||
|
||||
@end
|
||||
|
||||
@interface MPExpression (MPChangeNotificationExtension)
|
||||
|
||||
- (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length;
|
||||
|
||||
@end
|
||||
|
||||
@interface MPMutableExpression : MPExpression
|
||||
|
||||
- (void)replaceSymbolsInRange:(NSRange)range
|
||||
withSymbols:(NSArray *)symbols;
|
||||
|
||||
- (void)beginEditing;
|
||||
- (void)endEditing;
|
||||
|
||||
@end
|
||||
|
||||
@interface MPMutableExpression (MPMutableExpressionExtensionMethods)
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
#import "MPExpression.h"
|
||||
#import "MPFunction.h"
|
||||
#import "MPException.h"
|
||||
#import "MPRangePath.h"
|
||||
|
||||
#import "NSObject+MPStringTest.h"
|
||||
#import "NSIndexPath+MPRemoveFirstIndex.h"
|
||||
#import "NSIndexPath+MPReverseIndexPath.h"
|
||||
|
||||
NSString *MPAdditionOperator = @"+";
|
||||
NSString *MPSubtractionOperator = @"-";
|
||||
@@ -22,7 +23,6 @@ NSString *MPDivisionOperator = @"/";
|
||||
|
||||
- (NSInteger)lengthOfSymbol:(id)symbol;
|
||||
- (void)validateSymbols:(NSArray *)symbols;
|
||||
- (NSArray *)fixedSymbols:(NSArray *)symbols;
|
||||
- (void)getSplitOffset:(out NSUInteger *)offset
|
||||
inSymbolAtIndex:(out NSUInteger *)symbolIndex
|
||||
forSplitLocation:(NSUInteger)loc;
|
||||
@@ -53,7 +53,25 @@ NSString *MPDivisionOperator = @"/";
|
||||
|
||||
- (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
|
||||
@@ -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
|
||||
inSymbolAtIndex:(out NSUInteger *)symbolIndex
|
||||
forSplitLocation:(NSUInteger)loc
|
||||
@@ -420,9 +415,24 @@ NSString *MPDivisionOperator = @"/";
|
||||
|
||||
@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 {
|
||||
@protected
|
||||
NSInteger _editCount;
|
||||
NSRange editedRange;
|
||||
NSRange replacementRange;
|
||||
}
|
||||
|
||||
- (instancetype)initWithSymbols:(NSArray *)symbols
|
||||
@@ -430,6 +440,8 @@ NSString *MPDivisionOperator = @"/";
|
||||
[self validateSymbols:symbols];
|
||||
self = [super initWithSymbols:nil];
|
||||
if (self) {
|
||||
editedRange = NSMakeRange(0, 0);
|
||||
replacementRange = NSMakeRange(0, 0);
|
||||
_symbols = [[NSMutableArray alloc] initWithArray:symbols
|
||||
copyItems:YES];
|
||||
[self fixSymbols];
|
||||
@@ -439,7 +451,38 @@ NSString *MPDivisionOperator = @"/";
|
||||
|
||||
- (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
|
||||
@@ -460,22 +503,27 @@ NSString *MPDivisionOperator = @"/";
|
||||
|
||||
// Locate the position, split the symbols
|
||||
NSUInteger startIndex;
|
||||
BOOL didSplitStart = NO;
|
||||
if ([self numberOfSymbols] == 0) {
|
||||
startIndex = 0;
|
||||
} else {
|
||||
[self splitSymbolsAtLocation:range.location
|
||||
insertionIndex:&startIndex];
|
||||
insertionIndex:&startIndex
|
||||
didSplit:&didSplitStart];
|
||||
}
|
||||
|
||||
// Perform the deletion
|
||||
NSUInteger endIndex;
|
||||
BOOL didSplitEnd = NO;
|
||||
[self splitSymbolsAtLocation:NSMaxRange(range)
|
||||
insertionIndex:&endIndex
|
||||
didSplit:&didSplitEnd];
|
||||
if (range.length > 0) {
|
||||
NSUInteger endIndex;
|
||||
[self splitSymbolsAtLocation:NSMaxRange(range)
|
||||
insertionIndex:&endIndex];
|
||||
NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init];
|
||||
for (NSUInteger index = startIndex; index < endIndex; index++) {
|
||||
[indexes addIndex:index];
|
||||
}
|
||||
// TODO: Replace with removeObjectsInRange:
|
||||
[(NSMutableArray *)_symbols removeObjectsAtIndexes:indexes];
|
||||
}
|
||||
|
||||
@@ -486,15 +534,20 @@ NSString *MPDivisionOperator = @"/";
|
||||
withObjectsFromArray:newSymbols];
|
||||
}
|
||||
|
||||
// Revalidate structure and invalidate length
|
||||
if (_editCount == 0) {
|
||||
[self fixSymbols];
|
||||
}
|
||||
// Invalidate length and revalidate structure
|
||||
_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
|
||||
insertionIndex:(out NSUInteger *)insertionIndex
|
||||
didSplit:(out BOOL *)flag;
|
||||
{
|
||||
NSUInteger splitSymbolIndex;
|
||||
NSUInteger splitOffset;
|
||||
@@ -516,25 +569,10 @@ NSString *MPDivisionOperator = @"/";
|
||||
[(NSMutableArray *)_symbols insertObject:rightPart
|
||||
atIndex:splitSymbolIndex];
|
||||
}
|
||||
*flag = splitOffset != 0;
|
||||
*insertionIndex = splitSymbolIndex;
|
||||
}
|
||||
|
||||
- (void)beginEditing
|
||||
{
|
||||
_editCount++;
|
||||
}
|
||||
|
||||
- (void)endEditing
|
||||
{
|
||||
if (_editCount == 0) {
|
||||
return;
|
||||
}
|
||||
_editCount--;
|
||||
if (_editCount == 0) {
|
||||
[self fixSymbols];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPMutableExpression (MPMutableExpressionExtensionMethods)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||
//
|
||||
|
||||
@class MPFunction, MPExpression;
|
||||
@class MPFunction, MPExpression, MPRangePath;
|
||||
|
||||
@interface MPFunction : NSObject <NSCopying, NSCoding>
|
||||
|
||||
@@ -55,3 +55,9 @@
|
||||
- (NSUInteger)hash;
|
||||
|
||||
@end
|
||||
|
||||
@interface MPFunction (MPDisplayExtension)
|
||||
|
||||
- (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length;
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
|
||||
#import "MPFunction.h"
|
||||
#import "MPExpression.h"
|
||||
#import "MPRangePath.h"
|
||||
|
||||
#import "NSIndexPath+MPRemoveFirstIndex.h"
|
||||
#import "NSIndexPath+MPReverseIndexPath.h"
|
||||
|
||||
@implementation MPFunction
|
||||
|
||||
@@ -157,3 +158,15 @@
|
||||
}
|
||||
|
||||
@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
|
||||
Reference in New Issue
Block a user