Change cursor location with navigating buttons
Hello,
I created two buttons which allow to navigate Left and navigate Right one position. I thought by just calling previous and next on the _mathIndex it would go over the whole equation. However, if there are fractions or square roots, or an any atom of any other type it skips over them and does not enter them.
I thought maybe I should level up or level down depending if the next _mathIndex is of type fraction or root or whatever, but I had no luck. It just keeps skipping over them.
I'm guessing I have the logic of the class understood wrong. How am I supposed to be able to traverse 1 position at a time throughout the equation?
Also what I realized the [_insertionIndex next] will keep on incrementing the _insertionIndex.atomIndex even if there is nothing after the current index. For example,
5+5/5+10-9| <---- cursor at end of line will keep on going next and increment _insertionIndex.atomIndex. There should be some protection to see if it is at the end of the line do not increment
So far I cheap hacked it this way it works fine but too many mistakes while navigating occur: (This code goes in the MTEditableMathLabel.m)
- (void) goToInsertionIndexNext {
MTMathListIndex *savedIndex = _insertionIndex;
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x+(_label.fontSize-15), _caretView.frame.origin.y)];
if(savedIndex.subIndexType != kMTSubIndexTypeNumerator && _insertionIndex.subIndexType == kMTSubIndexTypeNumerator) {
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x-(_label.fontSize-10), _caretView.frame.origin.y+_label.fontSize+10)];
}
if([savedIndex isEqual:_insertionIndex]) {
_insertionIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x+(_label.fontSize-7), _caretView.frame.origin.y)];
} else {
_insertionIndex = savedIndex;
}
if (_insertionIndex == nil) {
_insertionIndex = [MTMathListIndex level0Index:self.mathList.atoms.count];
}
[_caretView showHandle:NO];
[self insertionPointChanged];
}
- (void) goToInsertionIndexDown{
MTMathListIndex *savedIndex = _insertionIndex;
if([savedIndex hasSubIndexOfType:kMTSubIndexTypeNumerator]) {
if([savedIndex previous]) {
savedIndex = [_insertionIndex previous];
} else {
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x, _caretView.frame.origin.y+(_label.fontSize+20))];
}
} else if([savedIndex hasSubIndexOfType:kMTSubIndexTypeDegree]){
if([savedIndex previous]) {
savedIndex = [_insertionIndex previous];
} else {
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x-(_label.fontSize-12), _caretView.frame.origin.y)];
}
} else if([savedIndex hasSubIndexOfType:kMTSubIndexTypeRadicand]){
if([savedIndex previous]) {
savedIndex = [_insertionIndex previous];
} else {
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x-(_label.fontSize-12), _caretView.frame.origin.y)];
}
} else if([savedIndex hasSubIndexOfType:kMTSubIndexTypeDenominator]) {
if([savedIndex previous]) {
savedIndex = [_insertionIndex previous];
} else {
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x-(_label.fontSize- 12), _caretView.frame.origin.y-(_label.fontSize+20))];
}
} else if([savedIndex hasSubIndexOfType:kMTSubIndexTypeSuperscript]) {
if([savedIndex previous]) {
savedIndex = [_insertionIndex previous];
} else {
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x-(_label.fontSize- 12), _caretView.frame.origin.y-(_label.fontSize+20))];
}
} else {
savedIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x-(_label.fontSize-10), _caretView.frame.origin.y)];
}
if([savedIndex isEqual:_insertionIndex]) {
_insertionIndex = [_insertionIndex previous];
if(!_insertionIndex) {
_insertionIndex = [self closestIndexToPoint:CGPointMake(_caretView.frame.origin.x-(_label.fontSize), _caretView.frame.origin.y)];
}
} else {
_insertionIndex = savedIndex;
}
if (_insertionIndex == nil) {
_insertionIndex = [MTMathListIndex level0Index:self.mathList.atoms.count];
}
[_caretView showHandle:NO];
[self insertionPointChanged];
}
I don't think you should use closestIndexToPoint, that seems kind of approximate.
I might be better to call previous and next and then look at the kind of element that is at that point and recurse inside it. This will take some special logic depending on type of atom. e.g. for fractions what should next do? Perhaps go to the numerator. After it is done with the numerator should it move on to the denominator or continue to the element after the fraction?
Yes I agree as I mentioned closestIndexToPoint was a cheap hack that shouldn't be used.
I had tried doing it with previous and next, however, recursing inside wouldn't work. It wouldn't realize if it has a subindex inside that index. Moreover, as I mentioned, when you get at the end of the equation where there is no more next. The next function would increment the index nevertheless.
Maybe it is because I didn't understand how to use the API correctly, but I will give it a try again. Can you give me tips on how to use the API. When I complete the code I'll post it on here.
Also, I agree the if there is a fraction while going forward it enters the numerator first and then the denominator, and vice versa on going backwards. Enter the denominator first, and then go back to the the numerator. And after it is done moving across the whole fraction, it goes to the next element.
Here is what i came up with today, and it works:
Must add this in MTMathList
- (NSUInteger) getListOfAtomsCount {
return _atoms.count;
}
- (void) goToInsertionIndexNext {
//Protection because the index keeps incrementing on next and application will crash
if(self.mathList.atoms.count != _insertionIndex.atomIndex) {
if(self.mathList.atoms[_insertionIndex.atomIndex].type == kMTMathAtomFraction) {
if(_insertionIndex.subIndexType == kMTSubIndexTypeNumerator && [((MTFraction *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).numerator getListOfAtomsCount] != _insertionIndex.subIndex.atomIndex) {
_insertionIndex = _insertionIndex.next;
} else if (_insertionIndex.subIndexType == kMTSubIndexTypeDenominator && [((MTFraction *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).denominator getListOfAtomsCount] != _insertionIndex.subIndex.atomIndex) {
_insertionIndex = _insertionIndex.next;
} else if (_insertionIndex.subIndexType == kMTSubIndexTypeNumerator) {
_insertionIndex = [[_insertionIndex levelDown] levelUpWithSubIndex:[MTMathListIndex level0Index:0] type:kMTSubIndexTypeDenominator];
} else if(_insertionIndex.subIndexType == kMTSubIndexTypeDenominator) {
_insertionIndex = [[_insertionIndex levelDown] next];
} else {
_insertionIndex = [_insertionIndex levelUpWithSubIndex:[MTMathListIndex level0Index:0] type:kMTSubIndexTypeNumerator];
}
} else if(self.mathList.atoms[_insertionIndex.atomIndex].type == kMTMathAtomRadical) {
if(_insertionIndex.subIndexType == kMTSubIndexTypeDegree && [((MTRadical *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).degree getListOfAtomsCount] != _insertionIndex.subIndex.atomIndex){
_insertionIndex = _insertionIndex.next;
} else if(_insertionIndex.subIndexType == kMTSubIndexTypeRadicand && [((MTRadical *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).radicand getListOfAtomsCount] != _insertionIndex.subIndex.atomIndex ){
_insertionIndex = _insertionIndex.next;
} else if (_insertionIndex.subIndexType == kMTSubIndexTypeDegree) {
_insertionIndex = [[_insertionIndex levelDown] levelUpWithSubIndex:[MTMathListIndex level0Index:0] type:kMTSubIndexTypeRadicand];
} else if (_insertionIndex.subIndexType == kMTSubIndexTypeRadicand) {
_insertionIndex = [[_insertionIndex levelDown] next];
} else {
if(((MTRadical *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).degree) {
_insertionIndex = [_insertionIndex levelUpWithSubIndex:[MTMathListIndex level0Index:[((MTRadical *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).degree getListOfAtomsCount]] type:kMTSubIndexTypeDegree];
} else {
_insertionIndex = [_insertionIndex levelUpWithSubIndex:[MTMathListIndex level0Index:0] type:kMTSubIndexTypeRadicand];
}
}
} else if(self.mathList.atoms[_insertionIndex.atomIndex].superScript) {
if(_insertionIndex.subIndexType == kMTSubIndexTypeSuperscript && [self.mathList.atoms[_insertionIndex.atomIndex].superScript getListOfAtomsCount] != _insertionIndex.subIndex.atomIndex) {
_insertionIndex = [_insertionIndex next];
} else if(_insertionIndex.subIndexType == kMTSubIndexTypeNucleus) {
_insertionIndex = [[_insertionIndex levelDown] levelUpWithSubIndex:[MTMathListIndex level0Index:0] type:kMTSubIndexTypeSuperscript];
}else if (_insertionIndex.subIndexType != kMTSubIndexTypeSuperscript) {
_insertionIndex = [_insertionIndex levelUpWithSubIndex:[MTMathListIndex level0Index:0] type:kMTSubIndexTypeSuperscript];
} else {
_insertionIndex = [[_insertionIndex levelDown] next];
}
} else {
_insertionIndex = [_insertionIndex next];
}
}
[self insertionPointChanged];
}
- (void) goToInsertionIndexDown{
MTMathListIndex *savedIndex = _insertionIndex.previous;
if(!savedIndex) {
if(_insertionIndex.subIndexType == kMTSubIndexTypeDenominator) {
_insertionIndex = [[_insertionIndex levelDown] levelUpWithSubIndex:[MTMathListIndex level0Index:[((MTFraction *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).numerator getListOfAtomsCount]]
type:kMTSubIndexTypeNumerator];
} else if (_insertionIndex.subIndexType == kMTSubIndexTypeNumerator) {
_insertionIndex = [_insertionIndex levelDown];
} else if(_insertionIndex.subIndexType == kMTSubIndexTypeRadicand) {
if( ((MTRadical *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).degree) {
_insertionIndex = [[_insertionIndex levelDown] levelUpWithSubIndex:[MTMathListIndex level0Index:[((MTRadical *)self.mathList.atoms[_insertionIndex.levelDown.atomIndex]).degree getListOfAtomsCount]] type:kMTSubIndexTypeDegree];
} else {
_insertionIndex = [_insertionIndex levelDown];
}
} else if (_insertionIndex.subIndexType == kMTSubIndexTypeDegree) {
_insertionIndex = [_insertionIndex levelDown];
} else if (_insertionIndex.subIndexType == kMTSubIndexTypeSuperscript) {
_insertionIndex = [_insertionIndex levelDown];
}
} else {
if(self.mathList.atoms[savedIndex.atomIndex].type == kMTMathAtomFraction) {
if(savedIndex.subIndexType == kMTSubIndexTypeDenominator) {
_insertionIndex = savedIndex;
} else if (savedIndex.subIndexType == kMTSubIndexTypeNumerator ) {
_insertionIndex = savedIndex;
} else {
_insertionIndex = [savedIndex levelUpWithSubIndex:[MTMathListIndex level0Index:[((MTFraction *)self.mathList.atoms[_insertionIndex.previous.atomIndex]).denominator getListOfAtomsCount]]
type:kMTSubIndexTypeDenominator];
}
}
// else if([savedIndex hasSubIndexOfType:kMTSubIndexTypeNumerator]) {
//
// }
else if(self.mathList.atoms[savedIndex.atomIndex].type == kMTMathAtomRadical) {
if(savedIndex.subIndexType == kMTSubIndexTypeRadicand){
_insertionIndex = savedIndex;
} else if ( savedIndex.subIndexType == kMTSubIndexTypeDegree) {
_insertionIndex = [_insertionIndex levelDown];
} else {
_insertionIndex = [savedIndex levelUpWithSubIndex:[MTMathListIndex level0Index:[((MTRadical *)self.mathList.atoms[_insertionIndex.previous.atomIndex]).radicand getListOfAtomsCount]]
type:kMTSubIndexTypeRadicand];
}
}
// else if ([savedIndex hasSubIndexOfType:kMTSubIndexTypeDegree]) {
//
// }
else if([savedIndex hasSubIndexOfType:kMTSubIndexTypeSuperscript]) {
if(savedIndex.subIndexType == kMTSubIndexTypeRadicand) {
_insertionIndex = savedIndex;
} else {
_insertionIndex = [savedIndex levelUpWithSubIndex:[MTMathListIndex level0Index:[((MTMathAtom *)self.mathList.atoms[_insertionIndex.previous.atomIndex]).superScript getListOfAtomsCount]]
type:kMTSubIndexTypeRadicand];
}
} else {
_insertionIndex = savedIndex;
}
}
[self insertionPointChanged];
}
There might be a few bugs and cases missing but it is a start
@kostub I have come with a solution to handle as many nested elements. I would like to send it to you so you can merge to main branch because I worked on the podfile instead of forking and adding. How can I send the code to you?
@kostub I have come with a solution to handle as many nested elements. I would like to send it to you so you can merge to main branch because I worked on the podfile instead of forking and adding. How can I send the code to you?
@serjooo : It would be great if you can provide updated one.. thanks..
@iosappsdevelopers Unfortunately, the code is long lost since I left the company I was working for 3 years ago
@serjooo : Okay, thanks for your response.