diff --git a/pupil_src/shared_modules/annotations.py b/pupil_src/shared_modules/annotations.py index 528bb136..04ca81a6 100644 --- a/pupil_src/shared_modules/annotations.py +++ b/pupil_src/shared_modules/annotations.py @@ -103,9 +103,7 @@ def init_ui(self): self.menu.append( ui.Button("Add Annotation Type", self._on_add_annotation_clicked) ) - self._annotation_list_menu = ui.Growing_Menu( - "Annotation List - Click to Remove" - ) + self._annotation_list_menu = ui.Growing_Menu("Annotation Types (click to remove)") self.menu.append(self._annotation_list_menu) self._create_initial_annotation_list() @@ -246,6 +244,8 @@ def __init__(self, g_pool, *args, **kwargs): self.last_frame_index = -1 self.timeline = None + self._frame_annotations_list = ui.Growing_Menu("Annotations in This Frame (click to remove)") + self._annotations_to_buttons = {} def init_ui(self): super().init_ui() @@ -258,6 +258,7 @@ def init_ui(self): self.glfont_raw = glfont_generator() self.g_pool.user_timelines.append(self.timeline) + self.menu.append(self._frame_annotations_list) def draw_timeline(self, width, height, scale): glfont = self.glfont_raw @@ -334,9 +335,12 @@ def fire_annotation(self, annotation_label): logger.info(annotation_desc) new_annotation = create_annotation(annotation_label, ts) new_annotation["added_in_player"] = True + + annotation = fm.Serialized_Dict(python_dict=new_annotation) self.annotations.insert( - new_annotation["timestamp"], fm.Serialized_Dict(python_dict=new_annotation) + new_annotation["timestamp"], annotation ) + self.add_frame_annotation_button(annotation) def recent_events(self, events): frame = events.get("frame") @@ -344,15 +348,31 @@ def recent_events(self, events): return self.last_frame_ts = frame.timestamp if frame.index != self.last_frame_index: + self._annotations_to_buttons.clear() + for item in list(self._frame_annotations_list): + self._frame_annotations_list.remove(item) + self.last_frame_index = frame.index frame_window = pm.enclosing_window(self.g_pool.timestamps, frame.index) - events = self.annotations.by_ts_window(frame_window) - for event in events: + annotations = self.annotations.by_ts_window(frame_window) + for annotation in annotations: annotation_desc = self._annotation_description( - label=event["label"], world_index=frame.index + label=annotation["label"], world_index=frame.index ) logger.info(annotation_desc) + self.add_frame_annotation_button(annotation) + + def add_frame_annotation_button(self, annotation): + button = ui.Button(label=annotation["label"], function=lambda: None) + button.function = lambda: self.delete_annotation(annotation) + self._frame_annotations_list.append(button) + self._annotations_to_buttons[annotation] = button + + def delete_annotation(self, annotation): + self.annotations.delete(annotation) + self._frame_annotations_list.remove(self._annotations_to_buttons[annotation]) + def on_notify(self, notification): if notification["subject"] == "should_export": self.export_annotations( diff --git a/pupil_src/shared_modules/player_methods.py b/pupil_src/shared_modules/player_methods.py index 204a00c0..5e58939a 100644 --- a/pupil_src/shared_modules/player_methods.py +++ b/pupil_src/shared_modules/player_methods.py @@ -121,6 +121,13 @@ def insert(self, timestamp, datum): self.data_ts = np.insert(self.data_ts, insert_idx, timestamp) self.data = np.insert(self.data, insert_idx, datum) + def delete(self, datum): + search = np.where(self.data == datum)[0] + if search: + idx = search[0] + self.data_ts = np.delete(self.data_ts, idx) + self.data = np.delete(self.data, idx) + class Affiliator(Bisector): """docstring for ClassName"""