From f68ccf5d8ee3e4916c765583a8f393d9a323a79e Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Mon, 21 Nov 2016 02:59:19 -0500 Subject: [PATCH 01/18] two finger swipe right basic impl --- Swift/VInput Keyboard/InputMode.swift | 9 ++++++++- Swift/VInput Keyboard/KeyboardViewController.swift | 6 ++---- Swift/VInput Keyboard/Mode.swift | 2 ++ Swift/VInput Keyboard/TutorialMode.swift | 7 +++++++ Swift/VInput Keyboard/ValueUtil.swift | 12 ++++++++---- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index 244bd60..9880f74 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -197,7 +197,7 @@ class InputMode : Mode { SpeechUtil.speak(textToSpeak: "Left or right of " + keyboardController.currentValues.getCurrentValue()) } - func onTwoTouchHold(){ + func onTwoTouchHold() { var text = "" if (currentWord != ""){ text = "Current word: " + currentWord @@ -209,6 +209,13 @@ class InputMode : Mode { } + func onTwoFingerSwipeRight() { + keyboardController.currentValues.resetIndexes() + let currentValueType: ValueUtil.VALUE_TYPE = keyboardController.currentValues.getValueType() + let numValueTypes: Int = ValueUtil.VALUE_TYPE.numValueTypes(currentValueType)() + 1 + ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE(rawValue: ((currentValueType.rawValue + 1) % numValueTypes))!) + VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) + } private func loadFromProxy() -> String { let textInDocumentProxy : [String] = keyboardController.textDocumentProxy.documentContextBeforeInput!.components(separatedBy: " ").filter{$0.isEmpty == false} diff --git a/Swift/VInput Keyboard/KeyboardViewController.swift b/Swift/VInput Keyboard/KeyboardViewController.swift index 2556fe8..18c227e 100644 --- a/Swift/VInput Keyboard/KeyboardViewController.swift +++ b/Swift/VInput Keyboard/KeyboardViewController.swift @@ -246,9 +246,7 @@ class KeyboardViewController: UIInputViewController { func onDoubleTap() { SpeechUtil.stopSpeech() -// currentMode!.doubleTap() - ValueUtil.swapMode(keyboardController: self, valueType: .numerical) - VisualUtil.updateViewAndAnnounce(letter: currentValues.getCurrentValue()) + currentMode!.doubleTap() } // TODO: Migrate Over -> Mike @@ -311,7 +309,7 @@ class KeyboardViewController: UIInputViewController { func onTwoFingerSwipeRight() { SpeechUtil.stopSpeech() - SpeechUtil.speak(textToSpeak: "Two Finger Swipe Right") + currentMode!.onTwoFingerSwipeRight() } func onThreeFingerSwipeRight() { diff --git a/Swift/VInput Keyboard/Mode.swift b/Swift/VInput Keyboard/Mode.swift index ed8a7e2..b076aaf 100644 --- a/Swift/VInput Keyboard/Mode.swift +++ b/Swift/VInput Keyboard/Mode.swift @@ -30,4 +30,6 @@ protocol Mode { func onTwoTouchHold() + func onTwoFingerSwipeRight() + } diff --git a/Swift/VInput Keyboard/TutorialMode.swift b/Swift/VInput Keyboard/TutorialMode.swift index c9921a2..13d2f92 100644 --- a/Swift/VInput Keyboard/TutorialMode.swift +++ b/Swift/VInput Keyboard/TutorialMode.swift @@ -115,11 +115,18 @@ class TutorialMode : Mode { ModeUtil.swapMode(keyboardController: keyboardController, stateKey: Key(index: tutorialIndex, trainingStrings: trainingStrings, callingMode: .tutorial), mode: .training) } + //*** STUBBED *** func onTwoTouchTap() { return } + //*** STUBBED *** func onTwoTouchHold() { return } + + //*** STUBBED *** + func onTwoFingerSwipeRight() { + return + } } diff --git a/Swift/VInput Keyboard/ValueUtil.swift b/Swift/VInput Keyboard/ValueUtil.swift index 0beb4cf..62430ac 100644 --- a/Swift/VInput Keyboard/ValueUtil.swift +++ b/Swift/VInput Keyboard/ValueUtil.swift @@ -10,13 +10,17 @@ import Foundation class ValueUtil { - enum VALUE_TYPE + enum VALUE_TYPE: Int { - case numerical - case lowercase + case lowercase = 0 case uppercase + case numerical case emoji - case training + + func numValueTypes() -> Int { + return VALUE_TYPE.emoji.rawValue + } + } static func swapMode(keyboardController: KeyboardViewController, valueType: VALUE_TYPE) From 668ba4df36434d651c0e0f487610773dec342527 Mon Sep 17 00:00:00 2001 From: Chen Date: Mon, 21 Nov 2016 03:11:54 -0500 Subject: [PATCH 02/18] slowed down tutorial and training speech rates and fixed hold issues in tutorial and training mode --- .../VInput Keyboard/KeyboardViewController.swift | 2 +- Swift/VInput Keyboard/SpeechUtil.swift | 5 +++-- Swift/VInput Keyboard/TrainingMode.swift | 16 ++++++++-------- Swift/VInput Keyboard/TutorialMode.swift | 14 +++++++------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Swift/VInput Keyboard/KeyboardViewController.swift b/Swift/VInput Keyboard/KeyboardViewController.swift index 27b7405..367aa87 100644 --- a/Swift/VInput Keyboard/KeyboardViewController.swift +++ b/Swift/VInput Keyboard/KeyboardViewController.swift @@ -248,7 +248,7 @@ class KeyboardViewController: UIInputViewController { override func viewDidAppear(_ animated: Bool) { currentMode = InputMode(keyboardController: self) - SpeechUtil.speak(textToSpeak: "Vinput Keyboard", preDelay: 0.5) + SpeechUtil.speak(textToSpeak: "VInput Keyboard", preDelay: 0.5) currentMode!.initialize() } diff --git a/Swift/VInput Keyboard/SpeechUtil.swift b/Swift/VInput Keyboard/SpeechUtil.swift index b5331e0..3d1a7d4 100644 --- a/Swift/VInput Keyboard/SpeechUtil.swift +++ b/Swift/VInput Keyboard/SpeechUtil.swift @@ -16,13 +16,14 @@ class SpeechUtil { static func speak(textToSpeak: String, pitchMultiplier: Float = 1.0, postDelay: TimeInterval = TimeInterval(0), - preDelay: TimeInterval = TimeInterval(0)) { + preDelay: TimeInterval = TimeInterval(0), + speechRate: Float = 0.55) { utterance = AVSpeechUtterance(string: textToSpeak) // TODO some of these values should be exposed as options in the Settings bundle utterance.pitchMultiplier = pitchMultiplier //utterance.postUtteranceDelay = postDelay utterance.preUtteranceDelay = preDelay - utterance.rate = 0.55 + utterance.rate = speechRate speechSynthesizer.speak(utterance) } diff --git a/Swift/VInput Keyboard/TrainingMode.swift b/Swift/VInput Keyboard/TrainingMode.swift index 41f2149..8f47375 100644 --- a/Swift/VInput Keyboard/TrainingMode.swift +++ b/Swift/VInput Keyboard/TrainingMode.swift @@ -39,7 +39,7 @@ class TrainingMode : InputMode { var text = "" if providedTrainingWords != nil { if stateIndex == 1 { - text = "Try finding the letter " + providedTrainingWords![0] + ". Hold on the screen with one finger when you find it" + text = "Try finding the letter " + providedTrainingWords![0] + ". Hold on the screen with one finger when you find it." } else if (stateIndex == 3) { text = "Try to spell out " + providedTrainingWords![0] @@ -51,12 +51,12 @@ class TrainingMode : InputMode { else { text = "The first word to spell is " + defaultTrainingWords[0] } - SpeechUtil.speak(textToSpeak: text) + SpeechUtil.speak(textToSpeak: text, speechRate: 0.5) VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) } override func onSwipeUp() { - SpeechUtil.speak(textToSpeak: "Inserting " + keyboardController.currentValues.getCurrentValue()) + SpeechUtil.speak(textToSpeak: "Inserting " + keyboardController.currentValues.getCurrentValue(), speechRate: 0.5) currentWord.append(keyboardController.currentValues.getCurrentValue()) keyboardController.currentValues.resetIndexes() VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) @@ -65,11 +65,11 @@ class TrainingMode : InputMode { override func swipeDown() { if !keyboardController.currentValues.isSearchingResetAndAnounce() { if trainingLevel.rawValue >= TRAINING_LEVELS.delete.rawValue && !currentWord.isEmpty { - SpeechUtil.speak(textToSpeak: "Deleting previous character") + SpeechUtil.speak(textToSpeak: "Deleting previous character", speechRate: 0.5) currentWord = currentWord.substring(to: currentWord.index(before: currentWord.endIndex)) } else { - SpeechUtil.speak(textToSpeak: "No characters in this word to delete") + SpeechUtil.speak(textToSpeak: "No characters in this word to delete", speechRate: 0.5) } } VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) @@ -82,7 +82,7 @@ class TrainingMode : InputMode { keyboardController.currentValues.resetIndexes() if trainingLevel == .space && startingIndex < key!.getStrings().count { - SpeechUtil.speak(textToSpeak: "Space inserted") + SpeechUtil.speak(textToSpeak: "Space inserted", speechRate: 0.5) } if shouldSwapBack && startingIndex >= key!.getStrings().count { @@ -92,11 +92,11 @@ class TrainingMode : InputMode { var text = "The next word to spell is " text += providedTrainingWords != nil ? providedTrainingWords![startingIndex] : defaultTrainingWords[startingIndex] - SpeechUtil.speak(textToSpeak: text) + SpeechUtil.speak(textToSpeak: text, speechRate: 0.5) } override func onLongHold() { - return + onHold() } enum TRAINING_LEVELS: Int { diff --git a/Swift/VInput Keyboard/TutorialMode.swift b/Swift/VInput Keyboard/TutorialMode.swift index 4600225..2ffd76e 100644 --- a/Swift/VInput Keyboard/TutorialMode.swift +++ b/Swift/VInput Keyboard/TutorialMode.swift @@ -44,11 +44,11 @@ class TutorialMode : Mode { func initialize() { KeyboardViewController.letterLabel.text = "" if tutorialIndex == 0 { - SpeechUtil.speak(textToSpeak: "You've entered tutorial mode.", postDelay: TimeInterval(4)) - SpeechUtil.speak(textToSpeak: tut[tutorialIndex], postDelay: TimeInterval(4)) + SpeechUtil.speak(textToSpeak: "You've entered tutorial mode.", postDelay: TimeInterval(4),speechRate: 0.5) + SpeechUtil.speak(textToSpeak: tut[tutorialIndex], postDelay: TimeInterval(4),speechRate: 0.5) tutorialIndex = tutorialIndex + 1 } - SpeechUtil.speak(textToSpeak: tut[tutorialIndex]) + SpeechUtil.speak(textToSpeak: tut[tutorialIndex], speechRate: 0.5) } @@ -61,7 +61,7 @@ class TutorialMode : Mode { if tutorialIndex > 0 { tutorialIndex = tutorialIndex - 1 } - SpeechUtil.speak(textToSpeak: tut[tutorialIndex]) + SpeechUtil.speak(textToSpeak: tut[tutorialIndex], speechRate: 0.5) } func onSwipeRight() { @@ -69,7 +69,7 @@ class TutorialMode : Mode { if tutorialIndex < tut.count{ tutorialIndex = tutorialIndex + 1 } - SpeechUtil.speak(textToSpeak: tut[tutorialIndex]) + SpeechUtil.speak(textToSpeak: tut[tutorialIndex], speechRate: 0.5) } func onSwipeUp() { @@ -79,13 +79,13 @@ class TutorialMode : Mode { func swipeDown() { SpeechUtil.stopSpeech() - SpeechUtil.speak(textToSpeak: "Exiting tutorial mode") + SpeechUtil.speak(textToSpeak: "Exiting tutorial mode", speechRate: 0.5) ModeUtil.swapMode(keyboardController: keyboardController, stateKey: Key(index: tutorialIndex, callingMode: .tutorial), mode: .input) } func doubleTap() { SpeechUtil.stopSpeech() - SpeechUtil.speak(textToSpeak: tut[tutorialIndex]) + SpeechUtil.speak(textToSpeak: tut[tutorialIndex], speechRate: 0.5) } func onHold() { From 51f9c0c02c86716332487b0472f4afd2b524d1ae Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Mon, 21 Nov 2016 03:09:01 -0500 Subject: [PATCH 03/18] swap values bug fix --- Swift/VInput Keyboard/InputMode.swift | 39 +++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index d157691..b7306b2 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -17,10 +17,12 @@ class InputMode : Mode { var keyboardController: KeyboardViewController! let MODE_NAME = "InputMode" var currentWord: String = "" + var swapBack: Bool = false init(keyboardController: KeyboardViewController) { // self.values = values self.keyboardController = keyboardController + self.swapBack = false } func initialize() { @@ -43,16 +45,18 @@ class InputMode : Mode { } func onSwipeLeft() { - if keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase { + if swapBack && keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase { ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE.lowercase) + swapBack = false } keyboardController.currentValues.shiftLeft() VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) } func onSwipeRight() { - if keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase { + if swapBack && keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase { ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE.lowercase) + swapBack = false } keyboardController.currentValues.shiftRight() VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) @@ -67,8 +71,9 @@ class InputMode : Mode { SpeechUtil.speak(textToSpeak: text) currentWord.append(keyboardController.currentValues.getCurrentValue()) keyboardController.textDocumentProxy.insertText(keyboardController.currentValues.getCurrentValue()) - if keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase{ + if swapBack && keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase{ ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE.lowercase) + swapBack = false } keyboardController.currentValues.resetIndexes() VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) @@ -119,21 +124,25 @@ class InputMode : Mode { } } - if keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase{ + if swapBack && keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase { ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE.lowercase) + swapBack = false } VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) } func onHold() { + //TODO: This needs to be refactored throughout if keyboardController.currentValues.getValueType() == .lowercase { ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE.uppercase) VisualUtil.updateView(letter: keyboardController.currentValues.getCurrentValue()) + swapBack = true SpeechUtil.speak(textToSpeak: "Current letter upper cased" ) } else if keyboardController.currentValues.getValueType() == .uppercase { ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE.lowercase) VisualUtil.updateView(letter: keyboardController.currentValues.getCurrentValue()) + swapBack = false SpeechUtil.speak(textToSpeak: "Current letter lower cased") } } @@ -214,11 +223,31 @@ class InputMode : Mode { func onTwoFingerSwipeRight() { - keyboardController.currentValues.resetIndexes() + let currentValueType: ValueUtil.VALUE_TYPE = keyboardController.currentValues.getValueType() let numValueTypes: Int = ValueUtil.VALUE_TYPE.numValueTypes(currentValueType)() + 1 ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE(rawValue: ((currentValueType.rawValue + 1) % numValueTypes))!) + + //TODO: Clean and refactor this + let valHolder: Int = keyboardController.currentValues.getValueType().rawValue + var text: String = "Switching to " + switch valHolder { + case 0: + text += "lower case alphabet" + case 1: + text += "upper case alphabet" + case 2: + text += "numbers 0 through 9" + case 3: + text += "emoticons" + default: + break + } + SpeechUtil.speak(textToSpeak: text) + + keyboardController.currentValues.resetIndexes() VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) + } private func loadFromProxy() -> String { From 54a3c7a7ff9c3e2be2425482771f58d40800f6bd Mon Sep 17 00:00:00 2001 From: chennyjen Date: Mon, 21 Nov 2016 03:24:43 -0500 Subject: [PATCH 04/18] Made longHold fire after 10 seconds instead of 4 --- Swift/VInput Keyboard/KeyboardViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Swift/VInput Keyboard/KeyboardViewController.swift b/Swift/VInput Keyboard/KeyboardViewController.swift index 229d714..b41b75f 100644 --- a/Swift/VInput Keyboard/KeyboardViewController.swift +++ b/Swift/VInput Keyboard/KeyboardViewController.swift @@ -156,7 +156,7 @@ class KeyboardViewController: UIInputViewController { shortHoldRecognizer.addTarget(self, action: #selector(onHold)) shortHoldRecognizer.require(toFail: longHoldRecognizer) - longHoldRecognizer.minimumPressDuration = TimeInterval(4) + longHoldRecognizer.minimumPressDuration = TimeInterval(10) longHoldRecognizer.numberOfTouchesRequired = 1 longHoldRecognizer.allowableMovement = 50 longHoldRecognizer.addTarget(self, action: #selector(onLongHold)) From 8417945c30429874d8aa0f8a998574ef0d637f01 Mon Sep 17 00:00:00 2001 From: Ryan Cesiel Date: Mon, 21 Nov 2016 07:08:15 -0500 Subject: [PATCH 05/18] add the testing document --- TESTING.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 TESTING.md diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000..f01e4dc --- /dev/null +++ b/TESTING.md @@ -0,0 +1,46 @@ +# VInput Testing +We discovered over the course of our project that the existing iOS testing environment is notably limited for 3rd party custom keyboards, and particularly for a more unconventional keyboard like ours. Therefore, we were not able to develop automated testing using these libraries as we originally hoped to. Instead, we devised a set of standard tests we could perform with major changes to test functionality. + +## Test 1: Basic Insertion +**Procedure:** Open the keyboard and swipe up. +**Expected Behavior:** The character ‘m’ should be inserted into the textbox and the corresponding announcement for this event is made. + +## Test 2: Bounds of the Alphabet are Constrained +**Procedure:** Swipe all the way until ‘a’ and then keep swiping left. +**Expected Behavior:** The user should be left with ‘a’ as their only option. + +## Test 3: Reset Selected Letter +**Procedure:** Open the keyboard, swipe right, then swipe down. +**Expected Behavior:** The current character should change from ‘m’ initially, to ’s’, and then reset back to ‘m’. + +## Test 4: Backspace Selected Letter +**Procedure:** Open the keyboard, swipe up, then swipe down. +**Expected Behavior:** The character ‘m’ should be inserted and then removed such that the text box is blank. + +## Test 5: Insert a Space +**Procedure:** Open the keyboard, swipe up, double tap, then swipe up. +**Expected Behavior:** There should be two 'm's separated by a space in the text field. + +## Test 6: Repeat Current Character +**Procedure:** After opening the keyboard, double tap once. +**Expected Behavior:** "Left or right of m" should be announced again. + +## Test 7: Repeat Previous Word +**Procedure:** Type the word "dog", and then hold with two fingers briefly anywhere on the screen. +**Expected Behavior:** The word “dog” should be read aloud. + +## Test 8: Uppercase the Current Letter +**Procedure:** Open the keyboard and hold one finger briefly and then release. +**Expected Behavior:** The letter 'm' should change from lowercase to uppercase + +## Test 9: Alphabet Toggle +**Procedure:** With the keyboard open, swipe right with two fingers. +**Expected Behavior:** The alphabet should change to either the emoji or number alphabets. + +## Test 10: Voice Over Toggle +**Procedure:** Turn VO on, open the keyboard, and swipe right with three fingers. +**Expected Behavior:** The “Next Keyboard” button should be selected; double tapping on the screen will change to the next keyboard. + +## Test 11: Close the Keyboard +**Procedure:** Open the keyboard and then pinch gesture anywhere on the screen. +**Expected Behavior:** The keyboard should slide down and dismiss. From 1a235343025192d9870fad42af68d2d792b496ed Mon Sep 17 00:00:00 2001 From: Ryan Cesiel Date: Mon, 21 Nov 2016 07:10:56 -0500 Subject: [PATCH 06/18] Updating formatting on TESTING.md --- TESTING.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TESTING.md b/TESTING.md index f01e4dc..684e2f3 100644 --- a/TESTING.md +++ b/TESTING.md @@ -3,44 +3,55 @@ We discovered over the course of our project that the existing iOS testing envir ## Test 1: Basic Insertion **Procedure:** Open the keyboard and swipe up. + **Expected Behavior:** The character ‘m’ should be inserted into the textbox and the corresponding announcement for this event is made. ## Test 2: Bounds of the Alphabet are Constrained **Procedure:** Swipe all the way until ‘a’ and then keep swiping left. + **Expected Behavior:** The user should be left with ‘a’ as their only option. ## Test 3: Reset Selected Letter **Procedure:** Open the keyboard, swipe right, then swipe down. + **Expected Behavior:** The current character should change from ‘m’ initially, to ’s’, and then reset back to ‘m’. ## Test 4: Backspace Selected Letter **Procedure:** Open the keyboard, swipe up, then swipe down. + **Expected Behavior:** The character ‘m’ should be inserted and then removed such that the text box is blank. ## Test 5: Insert a Space **Procedure:** Open the keyboard, swipe up, double tap, then swipe up. + **Expected Behavior:** There should be two 'm's separated by a space in the text field. ## Test 6: Repeat Current Character **Procedure:** After opening the keyboard, double tap once. + **Expected Behavior:** "Left or right of m" should be announced again. ## Test 7: Repeat Previous Word **Procedure:** Type the word "dog", and then hold with two fingers briefly anywhere on the screen. + **Expected Behavior:** The word “dog” should be read aloud. ## Test 8: Uppercase the Current Letter **Procedure:** Open the keyboard and hold one finger briefly and then release. + **Expected Behavior:** The letter 'm' should change from lowercase to uppercase ## Test 9: Alphabet Toggle **Procedure:** With the keyboard open, swipe right with two fingers. + **Expected Behavior:** The alphabet should change to either the emoji or number alphabets. ## Test 10: Voice Over Toggle **Procedure:** Turn VO on, open the keyboard, and swipe right with three fingers. + **Expected Behavior:** The “Next Keyboard” button should be selected; double tapping on the screen will change to the next keyboard. ## Test 11: Close the Keyboard **Procedure:** Open the keyboard and then pinch gesture anywhere on the screen. + **Expected Behavior:** The keyboard should slide down and dismiss. From f5e2a1025eb9c9dc41e255912fa4487f1867ac1b Mon Sep 17 00:00:00 2001 From: Ryan Cesiel Date: Mon, 21 Nov 2016 07:32:50 -0500 Subject: [PATCH 07/18] update README with beta features --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index e811706..7e2bb41 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,28 @@ As defined in our Alpha release project plan, below are the deliverables we have * Usability Testing Procedure and Results ([Google Drive](https://drive.google.com/drive/u/1/folders/0Bx_oMYCmW6jGZlgxR2RQTWlnYTg)) * Feature Discovery ([Google Drive](https://drive.google.com/drive/u/1/folders/0Bx_oMYCmW6jGZlgxR2RQTWlnYTg)) * "Hello World" full screen keyboard (GitHub) + +## Beta Release +As defined in our Beta release project plan, below are the deliverables we have completed: +* Algorithm logic + * The `Values` interface and subclasses primarily handle this logic +* Swiping/gesture setup + * Gestures registered in `KeyboardViewController.swift` include: swipe left, swipe right, swipe up, swipe down, hold, two finger swipe right, three finger swipe right, double tap, two finger hold, two finger tap, and pinch + * Gesture processing in `KeyboardViewController.swift` and primarily different mode files (i.e. `InputMode.swift`) +* Layout of keyboard + * Different UIView elements make up the visual interface within `KeyboardViewController.swift` +* Controller development and input processing + * `KeyboardViewController.swift` handles +* Voice prompting + * Pervasive use throughout the project of AVFoundation's `AVSpeechSynthesizer` +* Keyboard activation + * Initialization and setup upon triggered activation is found within `viewDidLoad()` of `KeyboardViewController.swift` +* "Happy path" testing: see TESTING.md + +We also went beyond these specified items in our project plan in completing the following: +* **VoiceOver Integration:** UI setup to switch between VoiceOver and VInput gestures and speech announcements +* **Tutorial and Training Modes:** informative and interactive guide and steps to using VInput +* **Multiple Alphabets:** users can two finger swipe between lowercase, uppercase, basic emoji and numeric alphabets +* **Fault Tolerance:** resiliency and correction against crashes, errors, faults by reloading in memory the last word where the user left off (allowing the user to continue where they left off) +* **CoreData Implementation:** as a user types right now, the words they type are stored on-device for later use in developing prediction features +* **Code Quality:** we spent significant time in the design of our code such that it is readable, maintainable, and extendable (i.e. inheritance in different input modes and alphabet values) From b80b43d815b4e65930021aa3de325fed919cb79c Mon Sep 17 00:00:00 2001 From: Ryan Cesiel Date: Mon, 21 Nov 2016 11:36:54 -0500 Subject: [PATCH 08/18] Updating information in README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e2bb41..55c61a1 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ As defined in our Beta release project plan, below are the deliverables we have * Layout of keyboard * Different UIView elements make up the visual interface within `KeyboardViewController.swift` * Controller development and input processing - * `KeyboardViewController.swift` handles + * `KeyboardViewController.swift` handles this in conjunction with different mode files (i.e. `InputMode.swift`) * Voice prompting * Pervasive use throughout the project of AVFoundation's `AVSpeechSynthesizer` * Keyboard activation @@ -32,5 +32,6 @@ We also went beyond these specified items in our project plan in completing the * **Tutorial and Training Modes:** informative and interactive guide and steps to using VInput * **Multiple Alphabets:** users can two finger swipe between lowercase, uppercase, basic emoji and numeric alphabets * **Fault Tolerance:** resiliency and correction against crashes, errors, faults by reloading in memory the last word where the user left off (allowing the user to continue where they left off) +* **Ensuring Correct Input:** correctly places the input cursor at the rightmost location in the text field to prevent accidental deletion and correct appending of additional characters * **CoreData Implementation:** as a user types right now, the words they type are stored on-device for later use in developing prediction features * **Code Quality:** we spent significant time in the design of our code such that it is readable, maintainable, and extendable (i.e. inheritance in different input modes and alphabet values) From 955079dd7ca65c2f2a206772dada8f5ed7bae774 Mon Sep 17 00:00:00 2001 From: Ryan Cesiel Date: Mon, 21 Nov 2016 11:44:51 -0500 Subject: [PATCH 09/18] Add link to Beta Release Features document --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55c61a1..e196277 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ As defined in our Alpha release project plan, below are the deliverables we have * "Hello World" full screen keyboard (GitHub) ## Beta Release -As defined in our Beta release project plan, below are the deliverables we have completed: +As defined in our Beta release project plan, below are the deliverables we have completed. [Additional and more detailed information can be found here](https://docs.google.com/document/d/1ckNWmpqcP-tZ3jRCnp_ZpskCHK__58Kwda_WcLUEZXA/edit?usp=sharing). * Algorithm logic * The `Values` interface and subclasses primarily handle this logic * Swiping/gesture setup From 2779e3bc63f4557c6629deca4f0fa80f0ef6173f Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Sun, 11 Dec 2016 01:12:44 -0500 Subject: [PATCH 10/18] punctuation keyboard impl --- Swift/VInput Keyboard/InputMode.swift | 5 +- Swift/VInput Keyboard/PunctuationValues.swift | 72 +++++++++++++++++++ Swift/VInput Keyboard/ValueUtil.swift | 6 +- Swift/VInput.xcodeproj/project.pbxproj | 14 +++- 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 Swift/VInput Keyboard/PunctuationValues.swift diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index b7306b2..642cdea 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -121,7 +121,7 @@ class InputMode : Mode { } else if keyboardController.textDocumentProxy.documentContextBeforeInput?.characters.last != " " { currentWord = loadFromProxy() - + //reload word here and decrement from count } } if swapBack && keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase { @@ -226,6 +226,7 @@ class InputMode : Mode { let currentValueType: ValueUtil.VALUE_TYPE = keyboardController.currentValues.getValueType() let numValueTypes: Int = ValueUtil.VALUE_TYPE.numValueTypes(currentValueType)() + 1 + print("$$$$$$ " + String(numValueTypes)) ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE(rawValue: ((currentValueType.rawValue + 1) % numValueTypes))!) //TODO: Clean and refactor this @@ -240,6 +241,8 @@ class InputMode : Mode { text += "numbers 0 through 9" case 3: text += "emoticons" + case 4: + text += "punctuation" default: break } diff --git a/Swift/VInput Keyboard/PunctuationValues.swift b/Swift/VInput Keyboard/PunctuationValues.swift new file mode 100644 index 0000000..e1f175c --- /dev/null +++ b/Swift/VInput Keyboard/PunctuationValues.swift @@ -0,0 +1,72 @@ +// +// Punctuation.swift +// VInput +// +// Created by Michael Vander Lugt on 12/10/16. +// Copyright © 2016 EECS481-VInput. All rights reserved. +// + +import Foundation + +class PunctuationValues : Values { + + let puncutationValues : [String] = [".","/",",","!","@","#","$","%", "^","&", "*", "(", ")"] +// let emojiValueNames: [String] = ["Angry", "Sad", "Neutral", "Grinning", "Very Happy"] + var index: Int + var valueType: ValueUtil.VALUE_TYPE + + init(values: [String] = [], valueType: ValueUtil.VALUE_TYPE = .punctuation) + { + self.index = 0 + self.valueType = .punctuation + } + + func shiftLeft() + { + if index > 0 + { + index -= 1 + } + } + + func shiftRight() { + if index < puncutationValues.count - 1 + { + index += 1 + } + } + + func getCurrentValue() -> String + { + return puncutationValues[index] + } + + func resetIndexes() { + index = 0 + } + + func getLeftIndex() -> Int { + return index + } + + func getRightIndex() -> Int { + return index + } + + func isSearchingResetAndAnounce() -> Bool { + if index != 0 { + index = 0 + return true + } + return false + } + + func getValueType() -> ValueUtil.VALUE_TYPE { + return valueType + } + + func isDone() -> Bool { + return index == (puncutationValues.count - 1) + } + +} diff --git a/Swift/VInput Keyboard/ValueUtil.swift b/Swift/VInput Keyboard/ValueUtil.swift index 62430ac..b702b1a 100644 --- a/Swift/VInput Keyboard/ValueUtil.swift +++ b/Swift/VInput Keyboard/ValueUtil.swift @@ -16,9 +16,11 @@ class ValueUtil { case uppercase case numerical case emoji + case punctuation func numValueTypes() -> Int { - return VALUE_TYPE.emoji.rawValue + //This is bad b/c hardcoded, but it's not like it even matters + return VALUE_TYPE.punctuation.rawValue } } @@ -34,6 +36,8 @@ class ValueUtil { toSwap = CapitalAlphaValues(valueType: .uppercase, presetLeftIndex: keyboardController.currentValues.getLeftIndex(), presetRightIndex: keyboardController.currentValues.getRightIndex()) case .emoji: toSwap = EmojiValues() + case .punctuation: + toSwap = PunctuationValues() default: toSwap = NumericalValues() } diff --git a/Swift/VInput.xcodeproj/project.pbxproj b/Swift/VInput.xcodeproj/project.pbxproj index 63edd80..1050bb0 100644 --- a/Swift/VInput.xcodeproj/project.pbxproj +++ b/Swift/VInput.xcodeproj/project.pbxproj @@ -23,6 +23,10 @@ CE2C0C3F1DDCDD4A0074BCEF /* TutorialMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2C0C3D1DDCDD4A0074BCEF /* TutorialMode.swift */; }; CE2C0C401DDCDD4A0074BCEF /* TutorialMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2C0C3D1DDCDD4A0074BCEF /* TutorialMode.swift */; }; CE2C0C411DDCDD4A0074BCEF /* TutorialMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2C0C3D1DDCDD4A0074BCEF /* TutorialMode.swift */; }; + CE38268B1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */; }; + CE38268C1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */; }; + CE38268D1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */; }; + CE38268E1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */; }; CED2B0A41DDD0C4E00A5827F /* Values.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED2B0A31DDD0C4E00A5827F /* Values.swift */; }; CED2B0A51DDD0C4E00A5827F /* Values.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED2B0A31DDD0C4E00A5827F /* Values.swift */; }; CED2B0A71DDD12E400A5827F /* SpeechUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED2B0A61DDD12E400A5827F /* SpeechUtil.swift */; }; @@ -106,6 +110,7 @@ CE2C0C331DDCDB790074BCEF /* Mode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mode.swift; sourceTree = ""; }; CE2C0C381DDCDB8D0074BCEF /* InputMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputMode.swift; sourceTree = ""; }; CE2C0C3D1DDCDD4A0074BCEF /* TutorialMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TutorialMode.swift; sourceTree = ""; }; + CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PunctuationValues.swift; sourceTree = ""; }; CED2B0A31DDD0C4E00A5827F /* Values.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Values.swift; sourceTree = ""; }; CED2B0A61DDD12E400A5827F /* SpeechUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpeechUtil.swift; sourceTree = ""; }; CED2B0A91DDD18C900A5827F /* LowerAlphaValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LowerAlphaValues.swift; sourceTree = ""; }; @@ -191,6 +196,7 @@ CEEE678E1DE2A29C0043A4F1 /* CapitalAlphaValues.swift */, CED2B0AC1DDD18E000A5827F /* EmojiValues.swift */, CED2B0AF1DDD326000A5827F /* TrainingValues.swift */, + CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */, ); name = Values; sourceTree = ""; @@ -356,7 +362,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "EECS481-VInput"; TargetAttributes = { FE3CCB6F1DC286DE0036DEF1 = { @@ -457,6 +463,7 @@ CED2B0B01DDD326000A5827F /* TrainingValues.swift in Sources */, 1D5E48AA1DDFEBA9008AE472 /* Prediction.xcdatamodeld in Sources */, FE3CCB761DC286DE0036DEF1 /* ViewController.swift in Sources */, + CE38268B1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, FE3CCB741DC286DE0036DEF1 /* AppDelegate.swift in Sources */, CEEE67841DE219860043A4F1 /* ModeUtil.swift in Sources */, CE2C0C391DDCDB8D0074BCEF /* InputMode.swift in Sources */, @@ -479,6 +486,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CE38268C1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, CE2C0C351DDCDB790074BCEF /* Mode.swift in Sources */, FE3CCB891DC286DE0036DEF1 /* VInputTests.swift in Sources */, CE2C0C3F1DDCDD4A0074BCEF /* TutorialMode.swift in Sources */, @@ -490,6 +498,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CE38268D1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, CE2C0C361DDCDB790074BCEF /* Mode.swift in Sources */, FE3CCB941DC286DE0036DEF1 /* VInputUITests.swift in Sources */, CE2C0C401DDCDD4A0074BCEF /* TutorialMode.swift in Sources */, @@ -511,6 +520,7 @@ CED2B0B11DDD326000A5827F /* TrainingValues.swift in Sources */, CED2B0BA1DDD420F00A5827F /* TrainingMode.swift in Sources */, CEEE67961DE2D2BC0043A4F1 /* NumericalValues.swift in Sources */, + CE38268E1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, CED2B0AE1DDD18E000A5827F /* EmojiValues.swift in Sources */, CED2B0A51DDD0C4E00A5827F /* Values.swift in Sources */, 1D5E48AC1DDFEE0B008AE472 /* AppDelegate.swift in Sources */, @@ -581,6 +591,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -630,6 +641,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; From a3e2c0f4ca93d3231f257e423df046a6184eefc8 Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Sun, 11 Dec 2016 13:50:58 -0500 Subject: [PATCH 11/18] most common words keyboard alive --- Swift/VInput Keyboard/InputMode.swift | 2 + .../KeyboardViewController.swift | 3 +- Swift/VInput Keyboard/MostCommonValues.swift | 102 ++++++++++++++++++ Swift/VInput Keyboard/PunctuationValues.swift | 22 ++-- Swift/VInput Keyboard/ValueUtil.swift | 5 +- Swift/VInput.xcodeproj/project.pbxproj | 10 ++ 6 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 Swift/VInput Keyboard/MostCommonValues.swift diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index 642cdea..1fe91f4 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -243,6 +243,8 @@ class InputMode : Mode { text += "emoticons" case 4: text += "punctuation" + case 5: + text += "your most common words" default: break } diff --git a/Swift/VInput Keyboard/KeyboardViewController.swift b/Swift/VInput Keyboard/KeyboardViewController.swift index b41b75f..0c8ecb0 100644 --- a/Swift/VInput Keyboard/KeyboardViewController.swift +++ b/Swift/VInput Keyboard/KeyboardViewController.swift @@ -277,7 +277,8 @@ class KeyboardViewController: UIInputViewController { func onSwipeDown() { SpeechUtil.stopSpeech() - currentMode!.swipeDown() +// currentMode!.swipeDown() + currentMode!.onTwoFingerSwipeRight() } func onSwipeRight() { diff --git a/Swift/VInput Keyboard/MostCommonValues.swift b/Swift/VInput Keyboard/MostCommonValues.swift new file mode 100644 index 0000000..4f11b1b --- /dev/null +++ b/Swift/VInput Keyboard/MostCommonValues.swift @@ -0,0 +1,102 @@ +// +// MostCommonValues.swift +// VInput +// +// Created by Michael Vander Lugt on 12/11/16. +// Copyright © 2016 EECS481-VInput. All rights reserved. +// + +import Foundation +import CoreData + +class MostCommonValues : Values +{ + + var commonValues : [Any] + var index: Int + var valueType: ValueUtil.VALUE_TYPE + + init(values: [String] = [], valueType: ValueUtil.VALUE_TYPE = .common_words, keyboardController: KeyboardViewController) + { + self.index = 0 + self.valueType = .common_words + self.commonValues = [] + let context = keyboardController.persistentContainer!.viewContext + let request = NSFetchRequest() + request.entity = NSEntityDescription.entity(forEntityName: "TypedWord", in: context) + request.sortDescriptors = [NSSortDescriptor(key: "frequency", ascending: false)] + do { + let results = try context.fetch(request) + if results.count > 0 { + // PRINT ALL WORDS + for result in results { + let word: String = (result as! TypedWord).word! + self.commonValues.append(word) + print(word) + print((result as! TypedWord).frequency) + + } + } + } catch { + let fetchError = error as NSError + print(fetchError) + } + } + + func shiftLeft() + { + if index > 0 + { + index -= 1 + } + } + + func shiftRight() + { + if index < commonValues.count - 1 + { + index += 1 + } + } + + func getCurrentValue() -> String + { + return String(describing: commonValues[index]) + } + + func resetIndexes() + { + index = 0 + } + + func getLeftIndex() -> Int + { + return index + } + + func getRightIndex() -> Int + { + return index + } + + func isSearchingResetAndAnounce() -> Bool + { + if index != 0 { + index = 0 + return true + } + return false + } + + func getValueType() -> ValueUtil.VALUE_TYPE + { + return valueType + } + + func isDone() -> Bool + { + return index == (commonValues.count - 1) + } + + +} diff --git a/Swift/VInput Keyboard/PunctuationValues.swift b/Swift/VInput Keyboard/PunctuationValues.swift index e1f175c..fa3ce3a 100644 --- a/Swift/VInput Keyboard/PunctuationValues.swift +++ b/Swift/VInput Keyboard/PunctuationValues.swift @@ -11,7 +11,6 @@ import Foundation class PunctuationValues : Values { let puncutationValues : [String] = [".","/",",","!","@","#","$","%", "^","&", "*", "(", ")"] -// let emojiValueNames: [String] = ["Angry", "Sad", "Neutral", "Grinning", "Very Happy"] var index: Int var valueType: ValueUtil.VALUE_TYPE @@ -29,7 +28,8 @@ class PunctuationValues : Values { } } - func shiftRight() { + func shiftRight() + { if index < puncutationValues.count - 1 { index += 1 @@ -41,19 +41,23 @@ class PunctuationValues : Values { return puncutationValues[index] } - func resetIndexes() { + func resetIndexes() + { index = 0 } - func getLeftIndex() -> Int { + func getLeftIndex() -> Int + { return index } - func getRightIndex() -> Int { + func getRightIndex() -> Int + { return index } - func isSearchingResetAndAnounce() -> Bool { + func isSearchingResetAndAnounce() -> Bool + { if index != 0 { index = 0 return true @@ -61,11 +65,13 @@ class PunctuationValues : Values { return false } - func getValueType() -> ValueUtil.VALUE_TYPE { + func getValueType() -> ValueUtil.VALUE_TYPE + { return valueType } - func isDone() -> Bool { + func isDone() -> Bool + { return index == (puncutationValues.count - 1) } diff --git a/Swift/VInput Keyboard/ValueUtil.swift b/Swift/VInput Keyboard/ValueUtil.swift index b702b1a..0371a97 100644 --- a/Swift/VInput Keyboard/ValueUtil.swift +++ b/Swift/VInput Keyboard/ValueUtil.swift @@ -17,10 +17,11 @@ class ValueUtil { case numerical case emoji case punctuation + case common_words func numValueTypes() -> Int { //This is bad b/c hardcoded, but it's not like it even matters - return VALUE_TYPE.punctuation.rawValue + return VALUE_TYPE.common_words.rawValue } } @@ -38,6 +39,8 @@ class ValueUtil { toSwap = EmojiValues() case .punctuation: toSwap = PunctuationValues() + case .common_words: + toSwap = MostCommonValues(keyboardController: keyboardController) default: toSwap = NumericalValues() } diff --git a/Swift/VInput.xcodeproj/project.pbxproj b/Swift/VInput.xcodeproj/project.pbxproj index 1050bb0..3a4c5db 100644 --- a/Swift/VInput.xcodeproj/project.pbxproj +++ b/Swift/VInput.xcodeproj/project.pbxproj @@ -27,6 +27,10 @@ CE38268C1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */; }; CE38268D1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */; }; CE38268E1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */; }; + CE3826901DFD2692000F81C3 /* MostCommonValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268F1DFD2692000F81C3 /* MostCommonValues.swift */; }; + CE3826911DFD2692000F81C3 /* MostCommonValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268F1DFD2692000F81C3 /* MostCommonValues.swift */; }; + CE3826921DFD2692000F81C3 /* MostCommonValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268F1DFD2692000F81C3 /* MostCommonValues.swift */; }; + CE3826931DFD2692000F81C3 /* MostCommonValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38268F1DFD2692000F81C3 /* MostCommonValues.swift */; }; CED2B0A41DDD0C4E00A5827F /* Values.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED2B0A31DDD0C4E00A5827F /* Values.swift */; }; CED2B0A51DDD0C4E00A5827F /* Values.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED2B0A31DDD0C4E00A5827F /* Values.swift */; }; CED2B0A71DDD12E400A5827F /* SpeechUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED2B0A61DDD12E400A5827F /* SpeechUtil.swift */; }; @@ -111,6 +115,7 @@ CE2C0C381DDCDB8D0074BCEF /* InputMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputMode.swift; sourceTree = ""; }; CE2C0C3D1DDCDD4A0074BCEF /* TutorialMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TutorialMode.swift; sourceTree = ""; }; CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PunctuationValues.swift; sourceTree = ""; }; + CE38268F1DFD2692000F81C3 /* MostCommonValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MostCommonValues.swift; sourceTree = ""; }; CED2B0A31DDD0C4E00A5827F /* Values.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Values.swift; sourceTree = ""; }; CED2B0A61DDD12E400A5827F /* SpeechUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpeechUtil.swift; sourceTree = ""; }; CED2B0A91DDD18C900A5827F /* LowerAlphaValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LowerAlphaValues.swift; sourceTree = ""; }; @@ -197,6 +202,7 @@ CED2B0AC1DDD18E000A5827F /* EmojiValues.swift */, CED2B0AF1DDD326000A5827F /* TrainingValues.swift */, CE38268A1DFD10C6000F81C3 /* PunctuationValues.swift */, + CE38268F1DFD2692000F81C3 /* MostCommonValues.swift */, ); name = Values; sourceTree = ""; @@ -465,6 +471,7 @@ FE3CCB761DC286DE0036DEF1 /* ViewController.swift in Sources */, CE38268B1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, FE3CCB741DC286DE0036DEF1 /* AppDelegate.swift in Sources */, + CE3826901DFD2692000F81C3 /* MostCommonValues.swift in Sources */, CEEE67841DE219860043A4F1 /* ModeUtil.swift in Sources */, CE2C0C391DDCDB8D0074BCEF /* InputMode.swift in Sources */, CEEE67951DE2D2BC0043A4F1 /* NumericalValues.swift in Sources */, @@ -489,6 +496,7 @@ CE38268C1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, CE2C0C351DDCDB790074BCEF /* Mode.swift in Sources */, FE3CCB891DC286DE0036DEF1 /* VInputTests.swift in Sources */, + CE3826911DFD2692000F81C3 /* MostCommonValues.swift in Sources */, CE2C0C3F1DDCDD4A0074BCEF /* TutorialMode.swift in Sources */, CE2C0C3A1DDCDB8D0074BCEF /* InputMode.swift in Sources */, ); @@ -501,6 +509,7 @@ CE38268D1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, CE2C0C361DDCDB790074BCEF /* Mode.swift in Sources */, FE3CCB941DC286DE0036DEF1 /* VInputUITests.swift in Sources */, + CE3826921DFD2692000F81C3 /* MostCommonValues.swift in Sources */, CE2C0C401DDCDD4A0074BCEF /* TutorialMode.swift in Sources */, CE2C0C3B1DDCDB8D0074BCEF /* InputMode.swift in Sources */, ); @@ -519,6 +528,7 @@ CEEE67851DE219860043A4F1 /* ModeUtil.swift in Sources */, CED2B0B11DDD326000A5827F /* TrainingValues.swift in Sources */, CED2B0BA1DDD420F00A5827F /* TrainingMode.swift in Sources */, + CE3826931DFD2692000F81C3 /* MostCommonValues.swift in Sources */, CEEE67961DE2D2BC0043A4F1 /* NumericalValues.swift in Sources */, CE38268E1DFD10C6000F81C3 /* PunctuationValues.swift in Sources */, CED2B0AE1DDD18E000A5827F /* EmojiValues.swift in Sources */, From 23c65e3cabcecde8f8305e05032b3932a1f70bd6 Mon Sep 17 00:00:00 2001 From: Chen Date: Sun, 11 Dec 2016 20:56:52 -0500 Subject: [PATCH 12/18] Fixed pronunciation of letter a in all modes --- Swift/VInput Keyboard/InputMode.swift | 10 +++++++++- Swift/VInput Keyboard/SpeechUtil.swift | 3 +++ Swift/VInput Keyboard/TrainingMode.swift | 2 +- Swift/VInput Keyboard/VisualUtil.swift | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index b7306b2..51fd0bf 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -68,6 +68,9 @@ class InputMode : Mode { if keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase{ text = "Inserting upper case " + keyboardController.currentValues.getCurrentValue() } + if keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.lowercase { + text = "Inserting " + keyboardController.currentValues.getCurrentValue().uppercased() + } SpeechUtil.speak(textToSpeak: text) currentWord.append(keyboardController.currentValues.getCurrentValue()) keyboardController.textDocumentProxy.insertText(keyboardController.currentValues.getCurrentValue()) @@ -207,7 +210,12 @@ class InputMode : Mode { func onTwoTouchTap() { - SpeechUtil.speak(textToSpeak: "Left or right of " + keyboardController.currentValues.getCurrentValue()) + if keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.lowercase { + SpeechUtil.speak(textToSpeak: "Left or right of " + keyboardController.currentValues.getCurrentValue().uppercased()) + } + else { + SpeechUtil.speak(textToSpeak: "Left or right of " + keyboardController.currentValues.getCurrentValue()) + } } func onTwoTouchHold() { diff --git a/Swift/VInput Keyboard/SpeechUtil.swift b/Swift/VInput Keyboard/SpeechUtil.swift index 3d1a7d4..51ef326 100644 --- a/Swift/VInput Keyboard/SpeechUtil.swift +++ b/Swift/VInput Keyboard/SpeechUtil.swift @@ -18,6 +18,9 @@ class SpeechUtil { postDelay: TimeInterval = TimeInterval(0), preDelay: TimeInterval = TimeInterval(0), speechRate: Float = 0.55) { +// if textToSpeak.range(of: " a") != nil { +// +// } utterance = AVSpeechUtterance(string: textToSpeak) // TODO some of these values should be exposed as options in the Settings bundle utterance.pitchMultiplier = pitchMultiplier diff --git a/Swift/VInput Keyboard/TrainingMode.swift b/Swift/VInput Keyboard/TrainingMode.swift index 8f47375..afd5eda 100644 --- a/Swift/VInput Keyboard/TrainingMode.swift +++ b/Swift/VInput Keyboard/TrainingMode.swift @@ -56,7 +56,7 @@ class TrainingMode : InputMode { } override func onSwipeUp() { - SpeechUtil.speak(textToSpeak: "Inserting " + keyboardController.currentValues.getCurrentValue(), speechRate: 0.5) + SpeechUtil.speak(textToSpeak: "Inserting " + keyboardController.currentValues.getCurrentValue().uppercased(), speechRate: 0.5) currentWord.append(keyboardController.currentValues.getCurrentValue()) keyboardController.currentValues.resetIndexes() VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) diff --git a/Swift/VInput Keyboard/VisualUtil.swift b/Swift/VInput Keyboard/VisualUtil.swift index d46699a..4cce176 100644 --- a/Swift/VInput Keyboard/VisualUtil.swift +++ b/Swift/VInput Keyboard/VisualUtil.swift @@ -13,7 +13,7 @@ class VisualUtil { static func updateViewAndAnnounce(letter: String) { KeyboardViewController.letterLabel.text = letter - let text = "Left or right of " + letter + let text = "Left or right of " + letter.uppercased() SpeechUtil.speak(textToSpeak: text) } From ed167dae9b19302c8a590ba0b39ecd5b152ec0f7 Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Sun, 11 Dec 2016 22:23:01 -0500 Subject: [PATCH 13/18] increments/decrements for last word when keyboard pinch closes/re-opens --- Swift/VInput Keyboard/InputMode.swift | 36 ++++++++++++++ .../KeyboardViewController.swift | 47 ++++++++++++++++--- Swift/VInput Keyboard/MostCommonValues.swift | 26 ++++++---- 3 files changed, 94 insertions(+), 15 deletions(-) diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index 1fe91f4..21e8e25 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -36,6 +36,24 @@ class InputMode : Mode { let textBeforeMarker: String? = keyboardController.textDocumentProxy.documentContextBeforeInput if textBeforeMarker != nil && textBeforeMarker!.characters.last != " " { currentWord = loadFromProxy() + //Need to decrement here - This is repeat code for now - same as swipe down + let context = self.keyboardController.persistentContainer!.viewContext + let request = NSFetchRequest() + request.predicate = NSPredicate(format: "word = %@", currentWord) + request.entity = NSEntityDescription.entity(forEntityName: "TypedWord", in: context) + + do { + let results = try context.fetch(request) + let wordToInsertOrUpdate: TypedWord? + if results.count > 0 { + wordToInsertOrUpdate = (results[0] as! TypedWord) + wordToInsertOrUpdate!.frequency -= 1 + try context.save() + } + } catch { + let fetchError = error as NSError + print(fetchError) + } } VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) } @@ -121,7 +139,25 @@ class InputMode : Mode { } else if keyboardController.textDocumentProxy.documentContextBeforeInput?.characters.last != " " { currentWord = loadFromProxy() + //reload word here and decrement from count + let context = self.keyboardController.persistentContainer!.viewContext + let request = NSFetchRequest() + request.predicate = NSPredicate(format: "word = %@", currentWord) + request.entity = NSEntityDescription.entity(forEntityName: "TypedWord", in: context) + + do { + let results = try context.fetch(request) + let wordToInsertOrUpdate: TypedWord? + if results.count > 0 { + wordToInsertOrUpdate = (results[0] as! TypedWord) + wordToInsertOrUpdate!.frequency -= 1 + try context.save() + } + } catch { + let fetchError = error as NSError + print(fetchError) + } } } if swapBack && keyboardController.currentValues.getValueType() == ValueUtil.VALUE_TYPE.uppercase { diff --git a/Swift/VInput Keyboard/KeyboardViewController.swift b/Swift/VInput Keyboard/KeyboardViewController.swift index 0c8ecb0..e1cb4c6 100644 --- a/Swift/VInput Keyboard/KeyboardViewController.swift +++ b/Swift/VInput Keyboard/KeyboardViewController.swift @@ -38,7 +38,11 @@ class KeyboardViewController: UIInputViewController { var currentMode: Mode? = nil var persistentContainer: NSPersistentContainer? - + + deinit { + print("%%%%%% DEINIT") + } + override func updateViewConstraints() { super.updateViewConstraints() @@ -204,12 +208,12 @@ class KeyboardViewController: UIInputViewController { var containerPath = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.VInput")! containerPath = URL(fileURLWithPath: documentsDirectory.appending("/store.sqlite"), isDirectory: false) // containerPath = containerPath.appendingPathComponent("store.sqlite") - do { - try FileManager.default.removeItem(at: containerPath) - } catch { - // nothing - print("Could not delete CD DB") - } +// do { +// try FileManager.default.removeItem(at: containerPath) +// } catch { +// // nothing +// print("Could not delete CD DB") +// } let description = NSPersistentStoreDescription(url: containerPath) container.persistentStoreDescriptions = [description] container.loadPersistentStores(completionHandler: { (storeDescription, error) in @@ -298,6 +302,35 @@ class KeyboardViewController: UIInputViewController { func onPinch() { SpeechUtil.stopSpeech() if pinchRecognizer.state == UIGestureRecognizerState.ended { + + //Hack for now + let textInDocumentProxy : [String] = self.textDocumentProxy.documentContextBeforeInput!.components(separatedBy: " ").filter{$0.isEmpty == false} + var lastWord = textInDocumentProxy.isEmpty ? "" : textInDocumentProxy.last! + + let context = self.persistentContainer!.viewContext + let request = NSFetchRequest() + + request.predicate = NSPredicate(format: "word = %@", lastWord) + request.entity = NSEntityDescription.entity(forEntityName: "TypedWord", in: context) + + do { + let results = try context.fetch(request) + let wordToInsertOrUpdate: TypedWord? + if results.count == 0 { + wordToInsertOrUpdate = NSEntityDescription.insertNewObject(forEntityName: "TypedWord", into: context) as! TypedWord + wordToInsertOrUpdate!.word = lastWord + wordToInsertOrUpdate!.frequency = 0 + } else { + wordToInsertOrUpdate = (results[0] as! TypedWord) + } + wordToInsertOrUpdate!.frequency += 1 + try context.save() + } catch { + let fetchError = error as NSError + print(fetchError) + } + //Code Repeat + self.dismissKeyboard() } } diff --git a/Swift/VInput Keyboard/MostCommonValues.swift b/Swift/VInput Keyboard/MostCommonValues.swift index 4f11b1b..d55122d 100644 --- a/Swift/VInput Keyboard/MostCommonValues.swift +++ b/Swift/VInput Keyboard/MostCommonValues.swift @@ -21,23 +21,32 @@ class MostCommonValues : Values self.index = 0 self.valueType = .common_words self.commonValues = [] + let context = keyboardController.persistentContainer!.viewContext let request = NSFetchRequest() request.entity = NSEntityDescription.entity(forEntityName: "TypedWord", in: context) request.sortDescriptors = [NSSortDescriptor(key: "frequency", ascending: false)] - do { + + do + { let results = try context.fetch(request) - if results.count > 0 { - // PRINT ALL WORDS - for result in results { + if results.count > 0 + { + for result in results + { let word: String = (result as! TypedWord).word! - self.commonValues.append(word) + let frequency = (result as! TypedWord).frequency + if frequency > 0 + { + self.commonValues.append(word) + } print(word) - print((result as! TypedWord).frequency) + print(frequency) } } - } catch { + } catch + { let fetchError = error as NSError print(fetchError) } @@ -81,7 +90,8 @@ class MostCommonValues : Values func isSearchingResetAndAnounce() -> Bool { - if index != 0 { + if index != 0 + { index = 0 return true } From 2edb9ceedbf5e135c3facae7ffa71ffd47bcefdb Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Sun, 11 Dec 2016 22:28:19 -0500 Subject: [PATCH 14/18] announce closing keyboard --- Swift/VInput Keyboard/KeyboardViewController.swift | 1 + Swift/VInput Keyboard/MostCommonValues.swift | 1 + 2 files changed, 2 insertions(+) diff --git a/Swift/VInput Keyboard/KeyboardViewController.swift b/Swift/VInput Keyboard/KeyboardViewController.swift index e1cb4c6..7ff0abe 100644 --- a/Swift/VInput Keyboard/KeyboardViewController.swift +++ b/Swift/VInput Keyboard/KeyboardViewController.swift @@ -364,6 +364,7 @@ class KeyboardViewController: UIInputViewController { func onThreeFingerSwipeRight() { SpeechUtil.stopSpeech() + SpeechUtil.speak(textToSpeak: "Exiting VInput.") // Renable normalVO functionality and allow user to transition // to another keyboard fullView.accessibilityTraits = UIAccessibilityTraitNone diff --git a/Swift/VInput Keyboard/MostCommonValues.swift b/Swift/VInput Keyboard/MostCommonValues.swift index d55122d..1b0678f 100644 --- a/Swift/VInput Keyboard/MostCommonValues.swift +++ b/Swift/VInput Keyboard/MostCommonValues.swift @@ -36,6 +36,7 @@ class MostCommonValues : Values { let word: String = (result as! TypedWord).word! let frequency = (result as! TypedWord).frequency + //Hack: not actually removing words from CoreData for now if frequency > 0 { self.commonValues.append(word) From a253cdc21ec376e41fba184f5b1dd8263e3fc0d6 Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Sun, 11 Dec 2016 23:08:49 -0500 Subject: [PATCH 15/18] emoji bug fix --- Swift/VInput Keyboard/EmojiValues.swift | 67 +++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/Swift/VInput Keyboard/EmojiValues.swift b/Swift/VInput Keyboard/EmojiValues.swift index ded993e..faa4e6b 100644 --- a/Swift/VInput Keyboard/EmojiValues.swift +++ b/Swift/VInput Keyboard/EmojiValues.swift @@ -8,13 +8,70 @@ import Foundation -class EmojiValues : InsertableValues { +class EmojiValues : Values { - let emojiValues : [String] = ["😡","☹","😐","😬","😃"] - let emojiValueNames: [String] = ["Angry", "Sad", "Neutral", "Grinning", "Very Happy"] + let emojiValues : [String] = ["😃","😊","😬","😐","☹","😭","😡"] + var index: Int + var valueType: ValueUtil.VALUE_TYPE - override init(values: [String] = [], valueType: ValueUtil.VALUE_TYPE = .emoji) { - super.init(values: emojiValues, valueType: valueType) + init(values: [String] = [], valueType: ValueUtil.VALUE_TYPE = .emoji) { + self.index = 0 + self.valueType = .emoji } + func shiftLeft() + { + if index > 0 + { + index -= 1 + } + } + + func shiftRight() + { + if index < emojiValues.count - 1 + { + index += 1 + } + } + + func getCurrentValue() -> String + { + return emojiValues[index] + } + + func resetIndexes() + { + index = 0 + } + + func getLeftIndex() -> Int + { + return index + } + + func getRightIndex() -> Int + { + return index + } + + func isSearchingResetAndAnounce() -> Bool + { + if index != 0 { + index = 0 + return true + } + return false + } + + func getValueType() -> ValueUtil.VALUE_TYPE + { + return valueType + } + + func isDone() -> Bool + { + return index == (emojiValues.count - 1) + } + } From 06c88ab44736913d5794563276208cac65ae63d3 Mon Sep 17 00:00:00 2001 From: Ryan Cesiel Date: Sun, 11 Dec 2016 23:11:43 -0500 Subject: [PATCH 16/18] fix speech from breaking; fix speech at end of swiping --- Swift/VInput Keyboard/InputMode.swift | 20 +++++++++++++++++--- Swift/VInput Keyboard/SpeechUtil.swift | 3 ++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index 76c8eed..dd43bf8 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -68,7 +68,14 @@ class InputMode : Mode { swapBack = false } keyboardController.currentValues.shiftLeft() - VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) + if keyboardController.currentValues.isDone() { + SpeechUtil.speak(textToSpeak: keyboardController.currentValues.getCurrentValue()) + SpeechUtil.speak(textToSpeak: "Swipe up to insert. Swipe down to reset.") + let systemSoundID: SystemSoundID = 4095 + AudioServicesPlaySystemSound (systemSoundID) + } else { + VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) + } } func onSwipeRight() { @@ -76,8 +83,15 @@ class InputMode : Mode { ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE.lowercase) swapBack = false } - keyboardController.currentValues.shiftRight() - VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) + if keyboardController.currentValues.isDone() { + SpeechUtil.speak(textToSpeak: keyboardController.currentValues.getCurrentValue()) + SpeechUtil.speak(textToSpeak: "Swipe up to insert. Swipe down to reset.") + let systemSoundID: SystemSoundID = 4095 + AudioServicesPlaySystemSound (systemSoundID) + } else { + keyboardController.currentValues.shiftRight() + VisualUtil.updateViewAndAnnounce(letter: keyboardController.currentValues.getCurrentValue()) + } } func onSwipeUp() { diff --git a/Swift/VInput Keyboard/SpeechUtil.swift b/Swift/VInput Keyboard/SpeechUtil.swift index 51ef326..c2a7b43 100644 --- a/Swift/VInput Keyboard/SpeechUtil.swift +++ b/Swift/VInput Keyboard/SpeechUtil.swift @@ -12,7 +12,7 @@ import AVFoundation class SpeechUtil { static var utterance: AVSpeechUtterance! - static let speechSynthesizer = AVSpeechSynthesizer() + static var speechSynthesizer = AVSpeechSynthesizer() static func speak(textToSpeak: String, pitchMultiplier: Float = 1.0, postDelay: TimeInterval = TimeInterval(0), @@ -37,6 +37,7 @@ class SpeechUtil { static func stopSpeech() { if speechSynthesizer.isSpeaking { speechSynthesizer.stopSpeaking(at: AVSpeechBoundary.immediate) + speechSynthesizer = AVSpeechSynthesizer() } } From 2ea4d91a6333af1ae4e442506cd9251d4b0fc309 Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Mon, 12 Dec 2016 00:06:13 -0500 Subject: [PATCH 17/18] punctuation speech fix --- Swift/VInput Keyboard/InputMode.swift | 3 +-- .../KeyboardViewController.swift | 7 +----- Swift/VInput Keyboard/PunctuationValues.swift | 3 ++- Swift/VInput Keyboard/SpeechUtil.swift | 24 +++++++++++++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Swift/VInput Keyboard/InputMode.swift b/Swift/VInput Keyboard/InputMode.swift index dd43bf8..89409a5 100644 --- a/Swift/VInput Keyboard/InputMode.swift +++ b/Swift/VInput Keyboard/InputMode.swift @@ -20,7 +20,6 @@ class InputMode : Mode { var swapBack: Bool = false init(keyboardController: KeyboardViewController) { -// self.values = values self.keyboardController = keyboardController self.swapBack = false } @@ -36,6 +35,7 @@ class InputMode : Mode { let textBeforeMarker: String? = keyboardController.textDocumentProxy.documentContextBeforeInput if textBeforeMarker != nil && textBeforeMarker!.characters.last != " " { currentWord = loadFromProxy() + //Need to decrement here - This is repeat code for now - same as swipe down let context = self.keyboardController.persistentContainer!.viewContext let request = NSFetchRequest() @@ -284,7 +284,6 @@ class InputMode : Mode { let currentValueType: ValueUtil.VALUE_TYPE = keyboardController.currentValues.getValueType() let numValueTypes: Int = ValueUtil.VALUE_TYPE.numValueTypes(currentValueType)() + 1 - print("$$$$$$ " + String(numValueTypes)) ValueUtil.swapMode(keyboardController: keyboardController, valueType: ValueUtil.VALUE_TYPE(rawValue: ((currentValueType.rawValue + 1) % numValueTypes))!) //TODO: Clean and refactor this diff --git a/Swift/VInput Keyboard/KeyboardViewController.swift b/Swift/VInput Keyboard/KeyboardViewController.swift index 7ff0abe..0f09a64 100644 --- a/Swift/VInput Keyboard/KeyboardViewController.swift +++ b/Swift/VInput Keyboard/KeyboardViewController.swift @@ -39,10 +39,6 @@ class KeyboardViewController: UIInputViewController { var persistentContainer: NSPersistentContainer? - deinit { - print("%%%%%% DEINIT") - } - override func updateViewConstraints() { super.updateViewConstraints() @@ -281,8 +277,7 @@ class KeyboardViewController: UIInputViewController { func onSwipeDown() { SpeechUtil.stopSpeech() -// currentMode!.swipeDown() - currentMode!.onTwoFingerSwipeRight() + currentMode!.swipeDown() } func onSwipeRight() { diff --git a/Swift/VInput Keyboard/PunctuationValues.swift b/Swift/VInput Keyboard/PunctuationValues.swift index fa3ce3a..9ab231d 100644 --- a/Swift/VInput Keyboard/PunctuationValues.swift +++ b/Swift/VInput Keyboard/PunctuationValues.swift @@ -10,7 +10,8 @@ import Foundation class PunctuationValues : Values { - let puncutationValues : [String] = [".","/",",","!","@","#","$","%", "^","&", "*", "(", ")"] + //Punctuation chosen based on http://mdickens.me/typing/letter_frequency.html + let puncutationValues : [String] = [",",".","-","\"","_","\'",")","(",";", "=",":", "/", "*", "!", "?", "$", "&", "@"] var index: Int var valueType: ValueUtil.VALUE_TYPE diff --git a/Swift/VInput Keyboard/SpeechUtil.swift b/Swift/VInput Keyboard/SpeechUtil.swift index c2a7b43..b76e55d 100644 --- a/Swift/VInput Keyboard/SpeechUtil.swift +++ b/Swift/VInput Keyboard/SpeechUtil.swift @@ -13,6 +13,26 @@ class SpeechUtil { static var utterance: AVSpeechUtterance! static var speechSynthesizer = AVSpeechSynthesizer() + static var punctuationKeys: [String:String] = [ + "Left or right of ," : "Left or right of comma", + "Left or right of ." : "Left or right of period", + "Left or right of -" : "Left or right of hyphen", + "Left or right of \"" : "Left or right of double quotation mark", + "Left or right of _" : "Left or right of underscore", + "Left or right of \'" : "Left or right of single quotation mark", + "Left or right of )" : "Left or right of close paranthesis", + "Left or right of (" : "Left or right of open paranthesis", + "Left or right of ;" : "Left or right of semi-colon", + "Left or right of =" : "Left or right of equal sign", + "Left or right of :" : "Left or right of colon", + "Left or right of /" : "Left or right of forward slash", + "Left or right of *" : "Left or right of asteric", + "Left or right of !" : "Left or right of exclamation point", + "Left or right of ?" : "Left or right of question mark", + "Left or right of $" : "Left or right of dollar sign", + "Left or right of &" : "Left or right of ampersand", + "Left or right of @" : "Left or right of at sign" + ] static func speak(textToSpeak: String, pitchMultiplier: Float = 1.0, postDelay: TimeInterval = TimeInterval(0), @@ -27,6 +47,10 @@ class SpeechUtil { //utterance.postUtteranceDelay = postDelay utterance.preUtteranceDelay = preDelay utterance.rate = speechRate + print(textToSpeak) + if let newText = punctuationKeys[textToSpeak] { + utterance = AVSpeechUtterance(string: newText) + } speechSynthesizer.speak(utterance) } From c2e4297f46b24bbaefc3a05d549a33bac6457ac9 Mon Sep 17 00:00:00 2001 From: Michael Vander Lugt Date: Mon, 12 Dec 2016 11:58:32 -0500 Subject: [PATCH 18/18] readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e196277..a4fa413 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,6 @@ We also went beyond these specified items in our project plan in completing the * **Ensuring Correct Input:** correctly places the input cursor at the rightmost location in the text field to prevent accidental deletion and correct appending of additional characters * **CoreData Implementation:** as a user types right now, the words they type are stored on-device for later use in developing prediction features * **Code Quality:** we spent significant time in the design of our code such that it is readable, maintainable, and extendable (i.e. inheritance in different input modes and alphabet values) + +## Gama Release +https://docs.google.com/a/umich.edu/document/d/1XTVoPCVIVRVMSoKFGWaqs9isXvAEo0pUQTC9SAfd9gM/edit?usp=sharing \ No newline at end of file