def test_ui_listbox_2d(recording=False): filename = "test_ui_listbox_2d" recording_filename = pjoin(DATA_DIR, filename + ".log.gz") expected_events_counts_filename = pjoin(DATA_DIR, filename + ".pkl") # Values that will be displayed by the listbox. values = list(range(1, 42 + 1)) listbox = ui.ListBox2D(values=values, size=(500, 500), multiselection=True, reverse_scrolling=False) listbox.center = (300, 300) # We will collect the sequence of values that have been selected. selected_values = [] def _on_change(): selected_values.append(list(listbox.selected)) # Set up a callback when selection changes. listbox.on_change = _on_change # Assign the counter callback to every possible event. event_counter = EventCounter() event_counter.monitor(listbox) # Create a show manager and record/play events. show_manager = window.ShowManager(size=(600, 600), title="DIPY ListBox") show_manager.ren.add(listbox) if recording: # Record the following events: # 1. Click on 1 # 2. Ctrl + click on 2, # 3. Ctrl + click on 2. # 4. Click on down arrow (4 times). # 5. Click on 21. # 6. Click on up arrow (5 times). # 7. Click on 1 # 8. Use mouse wheel to scroll down. # 9. Shift + click on 42. # 10. Use mouse wheel to scroll back up. show_manager.record_events_to_file(recording_filename) print(list(event_counter.events_counts.items())) event_counter.save(expected_events_counts_filename) else: show_manager.play_events_from_file(recording_filename) expected = EventCounter.load(expected_events_counts_filename) event_counter.check_counts(expected) # Check if the right values were selected. expected = [[1], [1, 2], [1], [21], [1], values] assert len(selected_values) == len(expected) assert_arrays_equal(selected_values, expected) # Test without multiselection enabled. listbox.multiselection = False del selected_values[:] # Clear the list. show_manager.play_events_from_file(recording_filename) # Check if the right values were selected. expected = [[1], [2], [2], [21], [1], [42]] assert len(selected_values) == len(expected) assert_arrays_equal(selected_values, expected)
def build_show(self, scene): title = 'Horizon ' + horizon_version self.show_m = window.ShowManager(scene, title=title, size=(1200, 900), order_transparent=True, reset_camera=False) self.show_m.initialize() if self.cluster and self.tractograms: lengths = np.array( [self.cla[c]['length'] for c in self.cla]) szs = [self.cla[c]['size'] for c in self.cla] sizes = np.array(szs) # global self.panel2, slider_length, slider_size self.panel2 = ui.Panel2D(size=(400, 200), position=(850, 670), color=(1, 1, 1), opacity=0.1, align="right") slider_label_threshold = build_label(text="Threshold") print("Cluster threshold", self.cluster_thr) slider_threshold = ui.LineSlider2D( min_value=5, max_value=25, initial_value=self.cluster_thr, text_template="{value:.0f}", length=140, shape='square') _color_slider(slider_threshold) slider_label_length = build_label(text="Length") slider_length = ui.LineSlider2D( min_value=lengths.min(), max_value=np.percentile(lengths, 98), initial_value=np.percentile(lengths, 25), text_template="{value:.0f}", length=140) _color_slider(slider_length) slider_label_size = build_label(text="Size") slider_size = ui.LineSlider2D( min_value=sizes.min(), max_value=np.percentile(sizes, 98), initial_value=np.percentile(sizes, 50), text_template="{value:.0f}", length=140) _color_slider(slider_size) # global self.length_min, size_min self.size_min = sizes.min() self.length_min = lengths.min() def change_threshold(istyle, obj, slider): sv = np.round(slider.value, 0) self.remove_cluster_actors(scene) self.add_cluster_actors(scene, self.tractograms, threshold=sv) # TODO need to double check if this section is still needed lengths = np.array( [self.cla[c]['length'] for c in self.cla]) szs = [self.cla[c]['size'] for c in self.cla] sizes = np.array(szs) slider_length.min_value = lengths.min() slider_length.max_value = lengths.max() slider_length.value = lengths.min() slider_length.update() slider_size.min_value = sizes.min() slider_size.max_value = sizes.max() slider_size.value = sizes.min() slider_size.update() self.length_min = min(lengths) self.size_min = min(sizes) self.show_m.render() slider_threshold.handle_events(slider_threshold.handle.actor) slider_threshold.on_left_mouse_button_released = change_threshold def hide_clusters_length(slider): self.length_min = np.round(slider.value) for k in self.cla: if (self.cla[k]['length'] < self.length_min or self.cla[k]['size'] < self.size_min): self.cla[k]['centroid_actor'].SetVisibility(0) if k.GetVisibility() == 1: k.SetVisibility(0) else: self.cla[k]['centroid_actor'].SetVisibility(1) self.show_m.render() def hide_clusters_size(slider): self.size_min = np.round(slider.value) for k in self.cla: if (self.cla[k]['length'] < self.length_min or self.cla[k]['size'] < self.size_min): self.cla[k]['centroid_actor'].SetVisibility(0) if k.GetVisibility() == 1: k.SetVisibility(0) else: self.cla[k]['centroid_actor'].SetVisibility(1) self.show_m.render() slider_length.on_change = hide_clusters_length # Clustering panel self.panel2.add_element(slider_label_threshold, coords=(0.1, 0.26)) self.panel2.add_element(slider_threshold, coords=(0.4, 0.26)) self.panel2.add_element(slider_label_length, coords=(0.1, 0.52)) self.panel2.add_element(slider_length, coords=(0.4, 0.52)) slider_size.on_change = hide_clusters_size self.panel2.add_element(slider_label_size, coords=(0.1, 0.78)) self.panel2.add_element(slider_size, coords=(0.4, 0.78)) scene.add(self.panel2) # Information panel text_block = build_label(HELP_MESSAGE, 18) text_block.message = HELP_MESSAGE self.help_panel = ui.Panel2D(size=(320, 200), color=(0.8, 0.8, 1), opacity=0.2, align="left") self.help_panel.add_element(text_block, coords=(0.05, 0.1)) scene.add(self.help_panel) if len(self.images) > 0: # !!Only first image loading supported for now') data, affine = self.images[0] self.vox2ras = affine if len(self.pams) > 0: pam = self.pams[0] else: pam = None self.panel = slicer_panel(scene, self.show_m.iren, data, affine, self.world_coords, pam=pam, mem=self.mem) else: data = None affine = None pam = None self.win_size = scene.GetSize() def win_callback(obj, event): if self.win_size != obj.GetSize(): size_old = self.win_size self.win_size = obj.GetSize() size_change = [self.win_size[0] - size_old[0], 0] if data is not None: self.panel.re_align(size_change) if self.cluster: self.panel2.re_align(size_change) self.help_panel.re_align(size_change) self.show_m.initialize() self.hide_centroids = True self.select_all = False def hide(): if self.hide_centroids: for ca in self.cea: if (self.cea[ca]['length'] >= self.length_min or self.cea[ca]['size'] >= self.size_min): if self.cea[ca]['selected'] == 0: ca.VisibilityOff() else: for ca in self.cea: if (self.cea[ca]['length'] >= self.length_min and self.cea[ca]['size'] >= self.size_min): if self.cea[ca]['selected'] == 0: ca.VisibilityOn() self.hide_centroids = not self.hide_centroids self.show_m.render() def invert(): for ca in self.cea: if (self.cea[ca]['length'] >= self.length_min and self.cea[ca]['size'] >= self.size_min): self.cea[ca]['selected'] = \ not self.cea[ca]['selected'] cas = self.cea[ca]['cluster_actor'] self.cla[cas]['selected'] = \ self.cea[ca]['selected'] self.show_m.render() def save(): saving_streamlines = Streamlines() for bundle in self.cla.keys(): if bundle.GetVisibility(): t = self.cla[bundle]['tractogram'] c = self.cla[bundle]['cluster'] indices = self.tractogram_clusters[t][c] saving_streamlines.extend(Streamlines(indices)) print('Saving result in tmp.trk') # Using the header of the first of the tractograms sft_new = StatefulTractogram(saving_streamlines, self.tractograms[0], Space.RASMM) save_tractogram(sft_new, 'tmp.trk', bbox_valid_check=False) print('Saved!') def new_window(): active_streamlines = Streamlines() for bundle in self.cla.keys(): if bundle.GetVisibility(): t = self.cla[bundle]['tractogram'] c = self.cla[bundle]['cluster'] indices = self.tractogram_clusters[t][c] active_streamlines.extend(Streamlines(indices)) # Using the header of the first of the tractograms active_sft = StatefulTractogram(active_streamlines, self.tractograms[0], Space.RASMM) hz2 = Horizon([active_sft], self.images, cluster=True, cluster_thr=self.cluster_thr/2., random_colors=self.random_colors, length_lt=np.inf, length_gt=0, clusters_lt=np.inf, clusters_gt=0, world_coords=True, interactive=True) ren2 = hz2.build_scene() hz2.build_show(ren2) def show_all(): if self.select_all is False: for ca in self.cea: if (self.cea[ca]['length'] >= self.length_min and self.cea[ca]['size'] >= self.size_min): self.cea[ca]['selected'] = 1 cas = self.cea[ca]['cluster_actor'] self.cla[cas]['selected'] = \ self.cea[ca]['selected'] self.show_m.render() self.select_all = True else: for ca in self.cea: if (self.cea[ca]['length'] >= self.length_min and self.cea[ca]['size'] >= self.size_min): self.cea[ca]['selected'] = 0 cas = self.cea[ca]['cluster_actor'] self.cla[cas]['selected'] = \ self.cea[ca]['selected'] self.show_m.render() self.select_all = False def expand(): for c in self.cea: if self.cea[c]['selected']: if not self.cea[c]['expanded']: len_ = self.cea[c]['length'] sz_ = self.cea[c]['size'] if (len_ >= self.length_min and sz_ >= self.size_min): self.cea[c]['cluster_actor']. \ VisibilityOn() c.VisibilityOff() self.cea[c]['expanded'] = 1 self.show_m.render() def reset(): for c in self.cea: if (self.cea[c]['length'] >= self.length_min and self.cea[c]['size'] >= self.size_min): self.cea[c]['cluster_actor'].VisibilityOff() c.VisibilityOn() self.cea[c]['expanded'] = 0 self.show_m.render() def key_press(obj, event): key = obj.GetKeySym() if self.cluster: # hide on/off unselected centroids if key == 'h' or key == 'H': hide() # invert selection if key == 'i' or key == 'I': invert() # retract help panel if key == 'o' or key == 'O': self.help_panel._set_position((-300, 0)) self.show_m.render() # save current result if key == 's' or key == 'S': save() if key == 'y' or key == 'Y': new_window() if key == 'a' or key == 'A': show_all() if key == 'e' or key == 'E': expand() if key == 'r' or key == 'R': reset() options = [r'un\hide centroids', 'invert selection', r'un\select all', 'expand clusters', 'collapse clusters', 'save streamlines', 'recluster'] listbox = ui.ListBox2D(values=options, position=(10, 300), size=(200, 270), multiselection=False, font_size=18) def display_element(): action = listbox.selected[0] if action == r'un\hide centroids': hide() if action == 'invert selection': invert() if action == r'un\select all': show_all() if action == 'expand clusters': expand() if action == 'collapse clusters': reset() if action == 'save streamlines': save() if action == 'recluster': new_window() listbox.on_change = display_element listbox.panel.opacity = 0.2 listbox.set_visibility(0) self.show_m.scene.add(listbox) def left_click_centroid_callback(obj, event): self.cea[obj]['selected'] = not self.cea[obj]['selected'] self.cla[self.cea[obj]['cluster_actor']]['selected'] = \ self.cea[obj]['selected'] self.show_m.render() def right_click_centroid_callback(obj, event): for lactor in listbox._get_actors(): lactor.SetVisibility(not lactor.GetVisibility()) listbox.scroll_bar.set_visibility(False) self.show_m.render() def left_click_cluster_callback(obj, event): if self.cla[obj]['selected']: self.cla[obj]['centroid_actor'].VisibilityOn() ca = self.cla[obj]['centroid_actor'] self.cea[ca]['selected'] = 0 obj.VisibilityOff() self.cea[ca]['expanded'] = 0 self.show_m.render() def right_click_cluster_callback(obj, event): print('Cluster Area Selected') self.show_m.render() for cl in self.cla: cl.AddObserver('LeftButtonPressEvent', left_click_cluster_callback, 1.0) cl.AddObserver('RightButtonPressEvent', right_click_cluster_callback, 1.0) self.cla[cl]['centroid_actor'].AddObserver( 'LeftButtonPressEvent', left_click_centroid_callback, 1.0) self.cla[cl]['centroid_actor'].AddObserver( 'RightButtonPressEvent', right_click_centroid_callback, 1.0) self.mem.window_timer_cnt = 0 def timer_callback(obj, event): self.mem.window_timer_cnt += 1 # TODO possibly add automatic rotation option # self.show_m.scene.azimuth(0.01 * self.mem.window_timer_cnt) # self.show_m.render() scene.reset_camera() scene.zoom(1.5) scene.reset_clipping_range() if self.interactive: self.show_m.add_window_callback(win_callback) self.show_m.add_timer_callback(True, 200, timer_callback) self.show_m.iren.AddObserver('KeyPressEvent', key_press) if self.return_showm: return self.show_m if self.recorded_events is None: self.show_m.render() self.show_m.start() else: # set to True if event recorded file needs updating recording = False recording_filename = self.recorded_events if recording: self.show_m.record_events_to_file(recording_filename) else: self.show_m.play_events_from_file(recording_filename) else: window.record(scene, out_path=self.out_png, size=(1200, 900), reset_camera=False)
previous_angle = slider.previous_value rotation_angle = angle - previous_angle cube_actor_1.RotateY(rotation_angle) ring_slider = ui.RingSlider2D(text_template="{angle:5.1f}°") ring_slider.center = (200, 200) ring_slider.on_change = rotate_red_cube """ 2D List Box =========== """ values = list(map(str, range(1, 50 + 1))) listbox = ui.ListBox2D(values=values, position=(300, 420), size=(250, 160), multiselection=True) def _print_nb_selected_elements(): msg = "{}/{} elements are now selected." print(msg.format(len(listbox.selected), len(listbox.values))) listbox.on_change = _print_nb_selected_elements """ Image Container ====== """ img = ui.ImageContainer2D(img_path=read_viz_icons(fname='home3.png'))
hide_all_examples() """ To make the menu, we'll first need to create a list of labels which correspond with the examples. """ values = [ 'Rectangle', 'Disks', 'Image', "Button Panel", "Line and Ring Slider", "Range Slider" ] """ Now we can create the menu. """ listbox = ui.ListBox2D(values=values, position=(10, 300), size=(300, 200), multiselection=False) """ Then we will use a callback to show the correct example when a label is clicked. """ def display_element(): hide_all_examples() example = examples[values.index(listbox.selected[0])] for element in example: element.set_visibility(True) if values.index(listbox.selected[0]) == 4: cube.SetVisibility(True)