99#import " ABBrailleReader.h"
1010#import " ABKeyboard.h"
1111#import " ABSpeak.h"
12+ #import " ABParser.h"
1213#import " UITextView+simpleadd.h"
1314
1415@implementation ABBrailleReader {
@@ -35,7 +36,8 @@ @implementation ABBrailleReader {
3536
3637}
3738
38- - (id )initWithAudioTarget : (id )tar selector : (SEL )sel {
39+ - (id )init
40+ {
3941 self = [super init ];
4042 if (self) {
4143 // init lookups
@@ -58,12 +60,18 @@ - (id)initWithAudioTarget:(id)tar selector:(SEL)sel {
5860
5961 // Setup parser
6062 prefix = @" " ;
61-
63+
64+ }
65+ return self;
66+ }
67+
68+ - (id )initWithAudioTarget : (id )tar selector : (SEL )sel {
69+ self = [self init ];
70+ if (self) {
6271 // Audio
6372 target = tar;
6473 selector = sel;
65- speak = [[ABSpeak alloc ] init ];
66-
74+ speak = [ABSpeak sharedInstance ];
6775 }
6876 return self;
6977}
@@ -90,11 +98,20 @@ + (NSString *)brailleStringFromTouchIDs:(NSArray *)touchIDs {
9098/* *
9199 * Receives character from touchLayer in form of braille string
92100 */
93- - (void )characterReceived : (NSString *)brailleString
94- {
95- [self sendCharacter: [self processString: brailleString]];
101+ - (NSString *)characterReceived : (NSString *)brailleString
102+ {
103+ NSString *returnChar = [self processString: brailleString];
104+ if ([returnChar isEqualToString: ABBackspace]) {
105+ [self sendBackspace ];
106+ } else if (returnChar) {
107+ [self sendCharacter: returnChar];
108+ }
109+ return returnChar;
96110}
97111
112+ /* *
113+ * Checks if a braille string is a prefix
114+ */
98115+ (BOOL )isValidPrefix : (NSString *)braille
99116{
100117 return ([braille isEqualToString: ABPrefixLevelOne] ||
@@ -119,112 +136,162 @@ - (NSString *)processString:(NSString *)brailleString
119136 }
120137
121138 // Intercept prefix operators
122- if ([ABBrailleReader isValidPrefix: prefix] && (_grade == ABGradeTwo) && ![brailleString isEqualToString: ABSpaceCharacter]) {
139+ if ((_grade == ABGradeTwo) && [ABBrailleReader isValidPrefix: prefix] && ![brailleString isEqualToString: ABSpaceCharacter]) {
123140 // Handle prefix
124- NSString *postfix = @" " ;
141+ NSString *postfixChar = @" " ;
125142 if ([prefix isEqualToString: ABPrefixNumber] && [[numberLookup allKeys ] containsObject: brailleString]) {
126- postfix = numberLookup[brailleString];
143+ postfixChar = numberLookup[brailleString];
127144 } else if ([prefix isEqualToString: ABPrefixLevelTwo] && [[prefixLevelTwo allKeys ] containsObject: brailleString]) {
128- postfix = prefixLevelTwo[brailleString];
145+ postfixChar = prefixLevelTwo[brailleString];
129146 } else if ([prefix isEqualToString: ABPrefixLevelThree] && [[prefixLevelThree allKeys ] containsObject: brailleString]) {
130- postfix = prefixLevelThree[brailleString];
147+ postfixChar = prefixLevelThree[brailleString];
131148 } else if ([prefix isEqualToString: ABPrefixLevelFour] && [[prefixLevelFour allKeys ] containsObject: brailleString]) {
132- postfix = prefixLevelFour[brailleString];
149+ postfixChar = prefixLevelFour[brailleString];
133150 } else if ([prefix isEqualToString: ABPrefixLevelFive] && [[prefixLevelFive allKeys ] containsObject: brailleString]) {
134- postfix = prefixLevelFive[brailleString];
151+ postfixChar = prefixLevelFive[brailleString];
135152 } else if ([prefix isEqualToString: ABPrefixLevelSix] && [[prefixLevelSix allKeys ] containsObject: brailleString]) {
136- postfix = prefixLevelSix[brailleString];
153+ postfixChar = prefixLevelSix[brailleString];
137154 } else if ([prefix isEqualToString: ABPrefixLevelSeven] && [[prefixLevelSeven allKeys ] containsObject: brailleString]) {
138- postfix = prefixLevelSeven[brailleString];
155+ postfixChar = prefixLevelSeven[brailleString];
139156 }
140- _wordTyping = [_wordTyping stringByAppendingString: postfix ];
157+ _wordTyping = [_wordTyping stringByAppendingString: postfixChar ];
141158 if (![prefix isEqualToString: ABPrefixNumber]) {
159+ // If prefix is not a number prefix, clear it
142160 prefix = @" " ;
143161 }
144- return postfix;
162+ // return as a send char
163+ return postfixChar;
145164
146165 } else {
147166 prefix = brailleString;
148- if ([ABBrailleReader isValidPrefix: prefix] && (_grade == ABGradeTwo)) {
149- // return if a valid prefix is set
150- return @" " ;
151- }
152- // if space proccess last typed word if grade two
167+ // return if a valid prefix is set because it's not a character.
168+ if ([ABBrailleReader isValidPrefix: prefix])
169+ return nil ;
170+
171+ // if space proccess last typed word if grade two for shorthand lookup.
153172 if ([brailleString isEqualToString: ABSpaceCharacter]) {
154- switch (_grade) {
155- case ABGradeOne:
156- break ;
157- case ABGradeTwo:
158- if ([[shortHandlookup allKeys ] containsObject: _wordTyping]) {
159- _wordTyping = shortHandlookup[_wordTyping];
160- }
161- break ;
173+ if (_grade == ABGradeTwo) {
174+ if ([[shortHandlookup allKeys ] containsObject: _wordTyping]) {
175+ _wordTyping = shortHandlookup[_wordTyping];
176+ // Handle updating textview corrently
177+ }
162178 }
163179 [self sendWord: _wordTyping];
164180 prefix = @" " ;
165181 _wordTyping = @" " ;
166- return @" " ;
182+ return nil ; // return nil to not send character
167183 }
168184
169185 // Is typed character
170- if (_grade == ABGradeOne && [grade2Lookup[brailleString] length ] > 1 ) {
171- return @" " ;
172- } else {
173- if ([[grade2Lookup allKeys ] containsObject: brailleString]) {
174- _wordTyping = [_wordTyping stringByAppendingString: grade2Lookup[brailleString]];
175- return grade2Lookup[brailleString];
176- } else {
177- return @" " ;
186+ if ([[grade2Lookup allKeys ] containsObject: brailleString]) {
187+ NSString *lookup = grade2Lookup[brailleString];
188+ switch (_grade) {
189+ case ABGradeOne:
190+ if (lookup.length == 1 ) { // Grade one is only single char
191+ // Check shift/caps
192+ if (_layer.shift ) {
193+ lookup = [lookup uppercaseString ];
194+ _layer.shift = NO ;
195+ [_layer setNeedsDisplay ];
196+ }
197+ if (_layer.caps ) {
198+ lookup = [lookup uppercaseString ];
199+ }
200+ _wordTyping = [_wordTyping stringByAppendingString: lookup];
201+ return lookup;
202+ }
203+ break ;
204+ case ABGradeTwo:
205+ // Check shift/caps
206+ if (_layer.shift ) {
207+ lookup = [NSString stringWithFormat: @" %@%@ " , [[lookup substringToIndex: 1 ] uppercaseString ], [lookup substringFromIndex: 1 ]];;
208+ _layer.shift = NO ;
209+ [_layer setNeedsDisplay ];
210+ }
211+ if (_layer.caps ) {
212+ lookup = [lookup uppercaseString ];
213+ }
214+ _wordTyping = [_wordTyping stringByAppendingString: lookup];
215+ return lookup;
216+ break ;
178217 }
179218 }
180219 }
220+ return nil ;
181221}
182222
223+ #pragma mark Handle updating with infomation
224+
183225- (void )sendCharacter : (NSString *)string
184226{
185- if ([string isEqualToString: ABSpaceCharacter]) {
186- [_fieldOutput insertText: @" " ];
187- [_delegate characterTyped: @" " withInfo: @{ABGestureInfoStatus : @(YES ),
188- ABSpaceTyped : @(YES ),
189- ABBackspaceReceived : @(NO )}];
190- } else if ([string isEqualToString: ABBackspace]) {
191- [_fieldOutput deleteBackward ];
192- [_delegate characterTyped: @" " withInfo: @{ABGestureInfoStatus : @(YES ),
193- ABSpaceTyped : @(NO ),
194- ABBackspaceReceived : @(YES )}];
195- [target performSelector: selector withObject: ABBackspaceSound];
196- } else if ([string isEqualToString: @" " ]) {
197- return ;
198- } else {
199- [speak speakString: string];
200-
201- if (_layer.shift ) {
202- string = [string uppercaseString ];
203- _layer.shift = NO ;
204- [_layer setNeedsDisplay ];
205- }
206- if (_layer.caps ) {
207- string = [string uppercaseString ];
208- }
209-
210- [_fieldOutput insertText: string];
211- [_delegate characterTyped: string withInfo: @{ABGestureInfoStatus : @(YES ),
212- ABSpaceTyped : @(NO ),
213- ABBackspaceReceived : @(NO )}];
214- }
227+ // Speak
228+ [speak speakString: string];
229+
230+ // Update _fieldOutput
231+ if (_fieldOutput)
232+ _fieldOutput.text = [_fieldOutput.text stringByAppendingString: string];
233+
234+ // Return char to delegate
235+ [self respondToDelegateWithInfo: @{ABGestureInfoStatus : @(YES ),
236+ ABSpaceTyped : @(NO ),
237+ ABBackspaceReceived : @(NO )}
238+ wordTyped: NO
239+ string: string];
215240}
216241
217242- (void )sendWord : (NSString *)string
218243{
219- NSLog ( @" Word Typed: %@ " , string);
244+ // Speak
220245 [speak speakString: string];
221- if (![string isEqualToString: ABSpaceCharacter]) {
222- [_fieldOutput replaceLastWordWithString: string];
246+
247+ // Update _fieldOutput
248+ if (_fieldOutput) {
249+ NSArray *words = [ABParser arrayOfWordsFromSentence: _fieldOutput.text];
250+ NSString *newSent = @" " ;
251+ for (int i = 0 ; i < words.count - 1 ; i++) {
252+ newSent = [newSent stringByAppendingString: words[i]];
253+ newSent = [newSent stringByAppendingString: @" " ];
254+ }
255+ _fieldOutput.text = [newSent stringByAppendingString: string];
256+ [_fieldOutput insertText: @" " ];
223257 }
224- [_fieldOutput insertText: @" " ];
225- [_delegate characterTyped: @" " withInfo: @{ABGestureInfoStatus : @(YES ),
226- ABSpaceTyped : @(YES ),
227- ABBackspaceReceived : @(NO )}];
258+ // Return word to delegate
259+ [self respondToDelegateWithInfo: @{ABGestureInfoStatus : @(YES ),
260+ ABSpaceTyped : @(YES ),
261+ ABBackspaceReceived : @(NO )}
262+ wordTyped: NO
263+ string: ABSpaceCharacter];
264+ [self respondToDelegateWithInfo: @{ABGestureInfoStatus : @(YES ),
265+ ABSpaceTyped : @(NO ),
266+ ABBackspaceReceived : @(NO )}
267+ wordTyped: YES
268+ string: string];
228269}
229270
271+ - (void )sendBackspace
272+ {
273+ // Update _fieldOutput
274+
275+ if (_fieldOutput && _fieldOutput.text .length > 0 )
276+ _fieldOutput.text = [_fieldOutput.text substringWithRange: NSMakeRange (0 , _fieldOutput.text.length - 1 )];
277+
278+ // Return backspace to delegate
279+ [self respondToDelegateWithInfo: @{ABGestureInfoStatus : @(YES ),
280+ ABSpaceTyped : @(NO ),
281+ ABBackspaceReceived : @(YES )}
282+ wordTyped: NO
283+ string: ABBackspace];
284+
285+ // Backspace sound
286+ [target performSelector: selector withObject: ABBackspaceSound];
287+ }
288+
289+ - (void )respondToDelegateWithInfo : (NSDictionary *)info wordTyped : (BOOL )word string : (NSString *)string
290+ {
291+ if (!word && [_delegate respondsToSelector: @selector (characterTyped:withInfo: )]) {
292+ [_delegate characterTyped: string withInfo: info];
293+ } else if (word && [_delegate respondsToSelector: @selector (wordTyped:withInfo: )]) {
294+ [_delegate wordTyped: string withInfo: info];
295+ }
296+ }
230297@end
0 commit comments