def test_single_stroke_in_char_with_space_ending_previous_char(self): chars = create_chars(['PS', 'SPS', 'PS']) # Deleting this: ^ # Expected result: merge with the preceding&following space new_chars, err_msg = delete_stroke(chars, DummySelectionHandler(chars, 1, 1)) self.assertEquals(2, len(new_chars)) if len(new_chars) != 2: return c0, c1 = chars self.assertEquals('PS', char_strokes(c0)) self.assertEquals('PS', char_strokes(c1)) self._validate_char_and_stroke_nums(chars) self.assertEquals(1, len(c0.strokes[0].trajectory)) self.assertEquals(4, len(c0.strokes[1].trajectory))
def test_delete_first_stroke_in_2nd_char(self): chars = create_chars(['PSPS', 'PSP', 'PS']) # Deleting this: ^ # Expected result: merge with the following space, and with the space at the end of the previous character new_chars, err_msg = delete_stroke(chars, DummySelectionHandler(chars, 1, 0)) self.assertEquals(3, len(new_chars)) if len(new_chars) != 3: return c0, c1, c2 = chars self.assertEquals('PSPS', char_strokes(c0)) self.assertEquals('P', char_strokes(c1)) self.assertEquals('PS', char_strokes(c2)) self._validate_char_and_stroke_nums(chars) self.assertEquals(3, len(c0.strokes[3].trajectory))
def test_delete_last_stroke_in_char_before_space(self): chars = create_chars(['PSPS', 'PSP', 'PS']) # Deleting this: ^ # Expected result: merge with the preceding space new_chars, err_msg = delete_stroke(chars, DummySelectionHandler(chars, 0, 2)) self.assertEquals(3, len(new_chars)) if len(new_chars) != 3: return c0, c1, c2 = chars self.assertEquals('PS', char_strokes(c0)) self.assertEquals('PSP', char_strokes(c1)) self.assertEquals('PS', char_strokes(c2)) self._validate_char_and_stroke_nums(chars) self.assertEquals(1, len(c0.strokes[0].trajectory)) self.assertEquals(3, len(c0.strokes[1].trajectory))
def test_single_stroke_in_char(self): chars = create_chars(['PSP', 'SPS', 'PS']) # Deleting this: ^ # Expected result: character deleted new_chars, err_msg = delete_stroke(chars, DummySelectionHandler(chars, 1, 1)) self.assertEquals(2, len(new_chars)) if len(new_chars) != 2: return c0, c1 = chars self.assertEquals('PSPS', char_strokes(c0)) self.assertEquals('PS', char_strokes(c1)) self._validate_char_and_stroke_nums(chars) self.assertEquals(1, len(c0.strokes[0].trajectory)) self.assertEquals(1, len(c0.strokes[1].trajectory)) self.assertEquals(1, len(c0.strokes[2].trajectory)) self.assertEquals(3, len(c0.strokes[3].trajectory))
def _try_encode_trial(trial, characters, sub_trial_num, out_dir, screen_size, margin, response): """" returns in this order: rc, characters, extra_info """ strokes = [s for c in characters for s in c.on_paper_strokes] all_markup_dots = [dot for c in characters for dot in c.on_paper_dots] #-- Skipping empty trials if len(strokes) == 0: dataio.save_trial(trial, '', 'empty', characters, sub_trial_num, out_dir) trial.processed = True return 'next_trial', None, None on_paper_chars = [c for c in characters if len(c.trajectory) > 0] on_paper_strokes = [s for s in strokes if len(s.trajectory) > 0] expand_ratio, offset, screen_size = _get_expand_ratio( all_markup_dots, screen_size, margin) title = 'Trial #{}, target={} ({} characters, {} strokes) '\ .format(trial.trial_id, trial.stimulus, len(on_paper_chars), len(on_paper_strokes)) window = _create_window_for_markup(screen_size, title, response or '') if len(on_paper_chars) < 2: window['merge_chars'].update(disabled=True) window['split_trial'].update(disabled=True) window['accept_error'].update(disabled=True) graph = window.Element('graph') instructions = window.Element('instructions') _plot_dots_for_markup(characters, graph, screen_size, expand_ratio, offset, margin) selection_handler = None current_command = None while True: cleanup_selection_handler = False event, values = window.Read() m = re.match('.+:(\\d+)', event) if m is not None: event = int(m.group(1)) #-- Window was closed: reset the trial if event is None: return 'reset_trial', None, None #-- Reset the trial elif event in ('r', 'R', 'reset_trial', 82, 'ר'): answer = sg.Popup( 'Reset trial', 'Are you sure you want to reset the current trial?', button_type=1) if answer == "Yes": window.Close() return 'reset_trial', None, None #-- Quit the app elif event in ('q', 'Q', 'quit', '/'): answer = sg.Popup('Quit', 'Are you sure you want to quit WEncoder?', button_type=1) if answer == "Yes": window.Close() return 'quit', None, None #-- Select trial elif event in ('g', 'G', 'choose_trial', 71, 'ע'): window.Close() return 'choose_trial', None, None #-- Open settings window elif event in ('e', 'E', 'settings', 69, 'ק'): window.Close() return 'settings', None, None #-- OK - Accept current coding if event in ('a', 'A', 'accept', 65, 'ש'): resp_optional = app_config[ 'response_mandatory'] == ResponseMandatory.Optional if not resp_optional: response = get_valid_user_response(response, on_paper_chars, trial.stimulus, get_if_already_exists=False) if resp_optional or response is not None: if sub_trial_num == 1: dataio.delete_trial(out_dir, trial.trial_id) dataio.save_trial(trial, response, "OK", characters, sub_trial_num, out_dir) trial.processed = True window.Close() return 'next_trial', None, None #-- Clicked on DropDown error elif event == 'error_code': if values['error_code'] in app_config["error_codes"]: window['accept_error'].update(disabled=False) #window['accept'].update(disabled=True) # else: # window['accept_error'].update(disabled=True) #-- Error - Accept current coding, set trial as error elif event in ('o', 'O', 'accept_error', 79, 'ם'): resp_optional = app_config[ 'response_mandatory'] != ResponseMandatory.MandatoryForAll if not resp_optional: response = get_valid_user_response(response, on_paper_chars, trial.stimulus, get_if_already_exists=False) if resp_optional or response is not None: if sub_trial_num == 1: dataio.delete_trial(out_dir, trial.trial_id) dataio.save_trial(trial, response, values['error_code'], characters, sub_trial_num, out_dir) trial.processed = True window.Close() return 'next_trial', None, None #-- Skip this trial elif event in ('k', 'K', 'skip_trial', 75, 'ל'): window.Close() return 'next_trial', None, None #-- Return to previous trial elif event in ('p', 'P', 'prev_trial', 80, 'פ'): window.Close() return 'prev_trial', None, None #-- Merge 2 characters elif event in ('m', 'M', 'merge_chars', 77, 'צ'): if current_command is None and len(characters) > 1: instructions.Update( 'Select the characters to merge. ENTER=confirm, ESC=abort') current_command = 'merge_chars' selection_handler = _CharsSelectorConsecutivePair( graph, characters) #-- Split a stroke into 2 characters elif event in ('s', 'S', 'split_stroke', 83, 'ד'): if current_command is None: instructions.Update( 'Select a stroke to split. ENTER=confirm, ESC=abort') current_command = 'split_stroke' selection_handler = _SingleStrokeSelector(graph, strokes) #-- Split a character elif event in ('c', 'C', 'split_char', 67, 'ב'): if current_command is None: instructions.Update( 'Select a character to split to 2 different characters. ENTER=confirm, ESC=abort' ) current_command = 'split_char' selection_handler = _MultiStrokeSelector( graph, characters, 'before') #-- Split the trial into 2 trials elif event in ('t', 'T', 'split_trial', 84, 'א'): if current_command is None: instructions.Update( 'Select the last character of trial#1. ENTER=confirm, ESC=abort' ) current_command = 'split_trial' selection_handler = _CharSeriesSelector(graph, characters) #-- Self correction elif event in ('x', 'X', 'set_extending_chars', 'ס'): if current_command is None: instructions.Update( 'Select 2 characters to connect as extending, or 1 char to un-extend. ENTER=confirm, ESC=abort' ) current_command = 'set_extending_chars' selection_handler = _CharSelectorAnyPair(graph, characters) # -- Show Self correction elif event == 'show_extending': app_config['show_extending'] = values['show_extending'] window.Close() return 'rerun', characters, None elif event in ('d', 'D', 'delete_stroke', 68, 'ג'): if current_command is None: instructions.Update( 'Select a stroke to delete. ENTER=confirm, ESC=abort') current_command = 'delete_stroke' selection_handler = _SingleStrokeSelector(graph, strokes) elif event == 'enter_response': response = get_valid_user_response(response, on_paper_chars, trial.stimulus, get_if_already_exists=True) window.Close() return 'rerun', characters, response #-- Mouse click elif event == 'graph': if selection_handler is not None: selection_handler.clicked(values) #-- ENTER clicked: end the currently-running command elif current_command is not None and not isinstance( event, int) and len(event) == 1 and ord(event) == 13: if current_command == 'split_char': characters = manip.split_character( characters, selection_handler.selected_char, selection_handler.selected_stroke) window.Close() return 'continue', characters, None elif current_command == 'merge_chars': characters = manip.merge_characters(characters, selection_handler.selected) window.Close() return 'continue', characters, None elif current_command == 'split_stroke': if selection_handler.selected is None: return 'continue', characters, None window.Close() return 'split_stroke', characters, selection_handler.selected elif current_command == 'split_trial': if selection_handler.selected is None: return 'continue', characters, None chars1, chars2 = manip.split_into_2_trials( characters, selection_handler.selected) window.Close() return 'split_trial', chars1, chars2 elif current_command == 'set_extending_chars': if len(selection_handler.selected_chars) == 0: return 'continue', characters, None _set_extending_characters(characters, selection_handler) window.Close() return 'rerun', characters, None elif current_command == 'delete_stroke': window.Close() try: characters, err_msg = manip.delete_stroke( characters, selection_handler) if err_msg is not None: messagebox.showerror('Invalid deletion attempt', err_msg) return 'rerun', characters, None except Exception as e: messagebox.showerror( 'Error in WEncoder', 'Error when trying to delete a character: {}'.format( e)) return 'rerun', characters, None else: messagebox.showerror('Error in WEncoder', 'General error (ENC-GEN-01)\nQuitting') return 'quit', None, None #-- ESC clicked: cancel the currently-running command #elif len(event) == 1 and ord(event) == 27: #Original line!!! else: if isinstance(event, str) and len(event) == 1: print("Clicked [{}] (#{})".format(event, ord(event))) else: print("Clicked [{}]".format(event)) instructions.Update('UNKNOWN COMMAND') if current_command is not None and ( event == 27 or (isinstance(event, str) and len(event) == 1 and ord(event) == 27)): cleanup_selection_handler = True if cleanup_selection_handler: instructions.Update('') current_command = None #if selection_handler is not None: selection_handler.cleanup() selection_handler = None