def start_mouse_tracker( ui, event_loop: asyncio.AbstractEventLoop, canvas_item: CanvasItem.AbstractCanvasItem, mouse_position_changed_by_fn: typing.Callable[[Geometry.IntPoint], None], global_pos: Geometry.IntPoint, size: Geometry.IntSize): tracking_canvas_item = TrackingCanvasItem() tracking_canvas_item.on_mouse_position_changed_by = mouse_position_changed_by_fn tracking_canvas_item.add_canvas_item(canvas_item) async def close_window(document_window): document_window.request_close() def handle_close(document_window): tracking_canvas_item.release_mouse() event_loop.create_task(close_window(document_window)) def activation_changed(document_window, activated): if not activated: handle_close(document_window) # create the popup window document_window = ui.create_document_window() document_window.window_style = "mousegrab" document_window.on_activation_changed = functools.partial( activation_changed, document_window) tracking_canvas_item.on_close = functools.partial(handle_close, document_window) # configure canvas widget, attach to document window mousegrab_window_pos = global_pos - Geometry.IntPoint(x=size.width, y=size.height / 2) document_window.show(size=size, position=mousegrab_window_pos) if sys.platform == "win32": relative_pos = Geometry.IntPoint() else: relative_pos = mousegrab_window_pos document_window.fill_screen() canvas_widget = ui.create_canvas_widget() tracking_canvas_item.sizing.set_fixed_size(size) content_row_canvas_item = CanvasItem.CanvasItemComposition() content_row_canvas_item.layout = CanvasItem.CanvasItemRowLayout() content_row_canvas_item.add_spacing(relative_pos.x) content_row_canvas_item.add_canvas_item(tracking_canvas_item) content_row_canvas_item.add_stretch() content_canvas_item = CanvasItem.CanvasItemComposition() content_canvas_item.layout = CanvasItem.CanvasItemColumnLayout() content_canvas_item.add_spacing(relative_pos.y) content_canvas_item.add_canvas_item(content_row_canvas_item) content_canvas_item.add_stretch() canvas_widget.canvas_item.add_canvas_item(content_canvas_item) document_window.attach(canvas_widget) tracking_canvas_item.request_focus() tracking_canvas_item.cursor_shape = "blank" canvas_widget.set_cursor_shape("blank") tracking_canvas_item.grab_mouse(relative_pos.x + size.width // 2, relative_pos.y + size.height // 2)
def __init__(self, ui, list_item_delegate, *, items=None, selection_style=None, properties=None, selection=None, border_color=None, v_scroll_enabled: bool=True, v_auto_resize: bool=False): super().__init__(ui.create_column_widget()) self.property_changed_event = Event.Event() items = items or list() self.__items: typing.List = list() self.on_selection_changed = None self.on_item_selected = None self.on_cancel = None self.on_item_handle_context_menu = None # used for declarative self.__items_binding = None self.__current_index_binding = None self.__on_current_index_changed = None self.__v_auto_resize = v_auto_resize self.on_escape_pressed : typing.Optional[typing.Callable[[], bool]] = None self.on_return_pressed : typing.Optional[typing.Callable[[], bool]] = None self.__selection = selection if selection else Selection.IndexedSelection(selection_style) def selection_changed(): on_selection_changed = self.on_selection_changed if callable(on_selection_changed): on_selection_changed(self.__selection.indexes) if callable(self.__on_current_index_changed): self.__on_current_index_changed(self.current_index) def handle_delegate_cancel(): if callable(self.on_cancel): self.on_cancel() if callable(self.on_escape_pressed): self.on_escape_pressed() def handle_delegate_item_selected(index): if callable(self.on_item_selected): self.on_item_selected(index) if callable(self.on_return_pressed): self.on_return_pressed() self.__selection_changed_event_listener = self.__selection.changed_event.listen(selection_changed) self.__list_canvas_item_delegate = list_item_delegate self.__list_canvas_item_delegate.on_cancel = handle_delegate_cancel self.__list_canvas_item_delegate.on_item_selected = handle_delegate_item_selected self.__list_canvas_item = ListCanvasItem.ListCanvasItem(self.__list_canvas_item_delegate, self.__selection, 20) scroll_area_canvas_item = CanvasItem.ScrollAreaCanvasItem(self.__list_canvas_item) scroll_area_canvas_item.auto_resize_contents = True scroll_group_canvas_item = CanvasItem.CanvasItemComposition() if border_color is not None: scroll_group_canvas_item.border_color = border_color scroll_group_canvas_item.layout = CanvasItem.CanvasItemRowLayout() scroll_group_canvas_item.add_canvas_item(scroll_area_canvas_item) if v_scroll_enabled: scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(scroll_area_canvas_item) scroll_group_canvas_item.add_canvas_item(scroll_bar_canvas_item) canvas_widget = ui.create_canvas_widget(properties=properties) canvas_widget.canvas_item.add_canvas_item(scroll_group_canvas_item) self.content_widget.add(canvas_widget) self.__canvas_widget = canvas_widget self.items = items
def __init__(self, display_panel, hardware_source_id): assert hardware_source_id is not None hardware_source = HardwareSource.HardwareSourceManager().get_hardware_source_for_hardware_source_id(hardware_source_id) self.type = VideoDisplayPanelController.type self.__hardware_source_id = hardware_source_id # configure the hardware source state controller self.__state_controller = VideoSourceStateController(hardware_source, display_panel.document_controller.queue_task, display_panel.document_controller.document_model) # configure the user interface self.__play_button_enabled = False self.__play_button_play_button_state = "play" self.__data_item_states = list() self.__display_panel = display_panel self.__display_panel.header_canvas_item.end_header_color = "#DAA520" self.__playback_controls_composition = CanvasItem.CanvasItemComposition() self.__playback_controls_composition.layout = CanvasItem.CanvasItemLayout() self.__playback_controls_composition.sizing.set_fixed_height(30) playback_controls_row = CanvasItem.CanvasItemComposition() playback_controls_row.layout = CanvasItem.CanvasItemRowLayout() play_button_canvas_item = CanvasItem.TextButtonCanvasItem() play_button_canvas_item.border_enabled = False abort_button_canvas_item = CanvasItem.TextButtonCanvasItem() abort_button_canvas_item.border_enabled = False status_text_canvas_item = CanvasItem.StaticTextCanvasItem(str()) hardware_source_display_name_canvas_item = CanvasItem.StaticTextCanvasItem(str()) playback_controls_row.add_canvas_item(play_button_canvas_item) playback_controls_row.add_canvas_item(abort_button_canvas_item) playback_controls_row.add_canvas_item(status_text_canvas_item) playback_controls_row.add_stretch() playback_controls_row.add_canvas_item(hardware_source_display_name_canvas_item) self.__playback_controls_composition.add_canvas_item(CanvasItem.BackgroundCanvasItem("#DAA520")) self.__playback_controls_composition.add_canvas_item(playback_controls_row) self.__display_panel.footer_canvas_item.insert_canvas_item(0, self.__playback_controls_composition) def display_name_changed(display_name): hardware_source_display_name_canvas_item.text = display_name hardware_source_display_name_canvas_item.size_to_content(display_panel.image_panel_get_font_metrics) def play_button_state_changed(enabled, play_button_state): play_button_canvas_item.enabled = enabled map_play_button_state_to_text = {"play": _("Play"), "pause": _("Pause")} play_button_canvas_item.text = map_play_button_state_to_text[play_button_state] play_button_canvas_item.size_to_content(display_panel.image_panel_get_font_metrics) def abort_button_state_changed(visible, enabled): abort_button_canvas_item.text = _("Abort") if visible else str() abort_button_canvas_item.enabled = enabled abort_button_canvas_item.size_to_content(display_panel.image_panel_get_font_metrics) def update_status_text(): map_channel_state_to_text = {"stopped": _("Stopped"), "complete": _("Acquiring"), "partial": _("Acquiring"), "marked": _("Stopping")} for data_item_state in self.__data_item_states: channel_state = data_item_state["channel_state"] new_text = map_channel_state_to_text[channel_state] if status_text_canvas_item.text != new_text: status_text_canvas_item.text = new_text status_text_canvas_item.size_to_content(display_panel.image_panel_get_font_metrics) return def data_item_states_changed(data_item_states): self.__data_item_states = data_item_states update_status_text() def display_data_item_changed(data_item): display_panel.set_displayed_data_item(data_item) def display_new_data_item(data_item): result_display_panel = display_panel.document_controller.next_result_display_panel() if result_display_panel: result_display_panel.set_display_panel_data_item(data_item) result_display_panel.request_focus() self.__state_controller.on_display_name_changed = display_name_changed self.__state_controller.on_play_button_state_changed = play_button_state_changed self.__state_controller.on_abort_button_state_changed = abort_button_state_changed self.__state_controller.on_data_item_states_changed = data_item_states_changed self.__state_controller.on_display_data_item_changed = display_data_item_changed self.__state_controller.on_display_new_data_item = display_new_data_item play_button_canvas_item.on_button_clicked = self.__state_controller.handle_play_clicked abort_button_canvas_item.on_button_clicked = self.__state_controller.handle_abort_clicked self.__state_controller.initialize_state() document_model = self.__display_panel.document_controller.document_model
def __init__(self, ui, items, selection_style=None, stringify_item=None, properties=None): super().__init__(ui.create_column_widget()) self.__items = items content_widget = self.content_widget self.on_selection_changed = None self.on_item_selected = None stringify_item = str if stringify_item is None else stringify_item class ListCanvasItemDelegate: def __init__(self, string_list_widget, items, selection): self.__string_list_widget = string_list_widget self.__items = items self.__selection = selection @property def items(self): return self.__items @items.setter def items(self, value): self.__items = value @property def item_count(self): return len(self.__items) def on_context_menu_event(self, index, x, y, gx, gy): return False def on_delete_pressed(self): pass def on_key_pressed(self, key): return False def on_drag_started(self, index, x, y, modifiers): pass def on_item_selected(self, index): if callable(self.__string_list_widget.on_item_selected): return self.__string_list_widget.on_item_selected(index) return False def paint_item(self, drawing_context, display_item, rect, is_selected): item = stringify_item(display_item) with drawing_context.saver(): drawing_context.fill_style = "#000" drawing_context.font = "12px" drawing_context.text_align = 'left' drawing_context.text_baseline = 'bottom' drawing_context.fill_text(item, rect[0][1] + 4, rect[0][0] + 20 - 4) self.__selection = Selection.IndexedSelection(selection_style) def selection_changed(): on_selection_changed = self.on_selection_changed if callable(on_selection_changed): on_selection_changed(self.__selection.indexes) self.__selection_changed_event_listener = self.__selection.changed_event.listen( selection_changed) self.__list_canvas_item_delegate = ListCanvasItemDelegate( self, items, self.__selection) self.__list_canvas_item = ListCanvasItem.ListCanvasItem( self.__list_canvas_item_delegate, self.__selection, 20) scroll_area_canvas_item = CanvasItem.ScrollAreaCanvasItem( self.__list_canvas_item) scroll_area_canvas_item.auto_resize_contents = True scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem( scroll_area_canvas_item) scroll_group_canvas_item = CanvasItem.CanvasItemComposition() scroll_group_canvas_item.border_color = "#888" scroll_group_canvas_item.layout = CanvasItem.CanvasItemRowLayout() scroll_group_canvas_item.add_canvas_item(scroll_area_canvas_item) scroll_group_canvas_item.add_canvas_item(scroll_bar_canvas_item) canvas_widget = ui.create_canvas_widget(properties=properties) canvas_widget.canvas_item.add_canvas_item(scroll_group_canvas_item) content_widget.add(canvas_widget)
def __init__(self, display_panel: DisplayPanel.DisplayPanel, hardware_source_id: str) -> None: assert hardware_source_id is not None hardware_source = HardwareSource.HardwareSourceManager( ).get_hardware_source_for_hardware_source_id(hardware_source_id) assert isinstance(hardware_source, video_base.VideoHardwareSource) self.type = VideoDisplayPanelController.type self.__hardware_source_id = hardware_source_id # configure the hardware source state controller self.__state_controller = VideoSourceStateController( hardware_source, display_panel.document_controller.queue_task, display_panel.document_controller.document_model) # configure the user interface self.__play_button_enabled = False self.__play_button_play_button_state = "play" self.__display_panel = display_panel self.__display_panel.header_canvas_item.end_header_color = "#DAA520" self.__playback_controls_composition = CanvasItem.CanvasItemComposition( ) self.__playback_controls_composition.layout = CanvasItem.CanvasItemLayout( ) self.__playback_controls_composition.update_sizing( self.__playback_controls_composition.sizing.with_fixed_height(30)) playback_controls_row = CanvasItem.CanvasItemComposition() playback_controls_row.layout = CanvasItem.CanvasItemRowLayout() play_button_canvas_item = CanvasItem.TextButtonCanvasItem() play_button_canvas_item.border_enabled = False abort_button_canvas_item = CanvasItem.TextButtonCanvasItem() abort_button_canvas_item.border_enabled = False status_text_canvas_item = CanvasItem.StaticTextCanvasItem(str()) hardware_source_display_name_canvas_item = CanvasItem.StaticTextCanvasItem( str()) playback_controls_row.add_canvas_item(play_button_canvas_item) playback_controls_row.add_canvas_item(abort_button_canvas_item) playback_controls_row.add_canvas_item(status_text_canvas_item) playback_controls_row.add_stretch() playback_controls_row.add_canvas_item( hardware_source_display_name_canvas_item) self.__playback_controls_composition.add_canvas_item( CanvasItem.BackgroundCanvasItem("#DAA520")) self.__playback_controls_composition.add_canvas_item( playback_controls_row) self.__display_panel.footer_canvas_item.insert_canvas_item( 0, self.__playback_controls_composition) def display_name_changed(display_name: str) -> None: hardware_source_display_name_canvas_item.text = display_name hardware_source_display_name_canvas_item.size_to_content( display_panel.image_panel_get_font_metrics) def play_button_state_changed(enabled: bool, play_button_state: str) -> None: play_button_canvas_item.enabled = enabled map_play_button_state_to_text = { "play": _("Play"), "pause": _("Pause") } play_button_canvas_item.text = map_play_button_state_to_text[ play_button_state] play_button_canvas_item.size_to_content( display_panel.image_panel_get_font_metrics) def abort_button_state_changed(visible: bool, enabled: bool) -> None: abort_button_canvas_item.text = _("Abort") if visible else str() abort_button_canvas_item.enabled = enabled abort_button_canvas_item.size_to_content( display_panel.image_panel_get_font_metrics) def acquisition_state_changed(key: str) -> None: # this may be called on a thread. create an async method (guaranteed to run on the main thread) # and add it to the window event loop. async def update_acquisition_state_label( acquisition_state: typing.Optional[str]) -> None: acquisition_state = acquisition_state or "stopped" status_text_canvas_item.text = map_channel_state_to_text[ acquisition_state] status_text_canvas_item.size_to_content( display_panel.image_panel_get_font_metrics) self.__display_panel.document_controller.event_loop.create_task( update_acquisition_state_label( self.__state_controller.acquisition_state_model.value)) def display_new_data_item(data_item: DataItem.DataItem) -> None: result_display_panel = display_panel.document_controller.next_result_display_panel( ) if result_display_panel: result_display_panel.set_display_panel_data_item(data_item) result_display_panel.request_focus() self.__state_controller.on_display_name_changed = display_name_changed self.__state_controller.on_play_button_state_changed = play_button_state_changed self.__state_controller.on_abort_button_state_changed = abort_button_state_changed self.__state_controller.on_display_new_data_item = display_new_data_item display_panel.set_data_item_reference( self.__state_controller.data_item_reference) play_button_canvas_item.on_button_clicked = self.__state_controller.handle_play_clicked abort_button_canvas_item.on_button_clicked = self.__state_controller.handle_abort_clicked self.__acquisition_state_changed_listener = self.__state_controller.acquisition_state_model.property_changed_event.listen( acquisition_state_changed) self.__state_controller.initialize_state() acquisition_state_changed("value")
def __init__(self, document_controller: DocumentController.DocumentController, panel_id: str, properties: typing.Dict): super().__init__(document_controller, panel_id, _("Data Items")) ui = document_controller.ui def show_context_menu(display_item: typing.Optional[DisplayItem.DisplayItem], x: int, y: int, gx: int, gy: int) -> bool: menu = document_controller.create_context_menu_for_display(display_item, use_selection=True) menu.popup(gx, gy) return True def map_display_item_to_display_item_adapter(display_item: DisplayItem.DisplayItem) -> DisplayItemAdapter: return DisplayItemAdapter(display_item, ui) def unmap_display_item_to_display_item_adapter(display_item_adapter: DisplayItemAdapter) -> None: display_item_adapter.close() self.__filtered_display_item_adapters_model = ListModel.MappedListModel(container=document_controller.filtered_display_items_model, master_items_key="display_items", items_key="display_item_adapters", map_fn=map_display_item_to_display_item_adapter, unmap_fn=unmap_display_item_to_display_item_adapter) self.__selection = self.document_controller.selection self.__focused = False def selection_changed() -> None: # called when the selection changes; notify selected display item changed if focused. self.__notify_focus_changed() self.__selection_changed_event_listener = self.__selection.changed_event.listen(selection_changed) def display_item_adapter_selection_changed(display_item_adapters: typing.List[DisplayItemAdapter]) -> None: indexes = set() for index, display_item_adapter in enumerate(self.__filtered_display_item_adapters_model.display_item_adapters): if display_item_adapter in display_item_adapters: indexes.add(index) self.__selection.set_multiple(indexes) self.__notify_focus_changed() def focus_changed(focused: bool) -> None: self.focused = focused def delete_display_item_adapters(display_item_adapters: typing.List[DisplayItemAdapter]) -> None: document_controller.delete_display_items([display_item_adapter.display_item for display_item_adapter in display_item_adapters if display_item_adapter.display_item]) self.data_list_controller = DataListController(document_controller.event_loop, ui, self.__filtered_display_item_adapters_model, self.__selection) self.data_list_controller.on_display_item_adapter_selection_changed = display_item_adapter_selection_changed self.data_list_controller.on_context_menu_event = show_context_menu self.data_list_controller.on_focus_changed = focus_changed self.data_list_controller.on_delete_display_item_adapters = delete_display_item_adapters self.data_grid_controller = DataGridController(document_controller.event_loop, ui, self.__filtered_display_item_adapters_model, self.__selection) self.data_grid_controller.on_display_item_adapter_selection_changed = display_item_adapter_selection_changed self.data_grid_controller.on_context_menu_event = show_context_menu self.data_grid_controller.on_focus_changed = focus_changed self.data_grid_controller.on_delete_display_item_adapters = delete_display_item_adapters data_list_widget = DataListWidget(ui, self.data_list_controller) data_grid_widget = DataGridWidget(ui, self.data_grid_controller) list_icon_button = CanvasItem.BitmapButtonCanvasItem(CanvasItem.load_rgba_data_from_bytes(pkgutil.get_data(__name__, "resources/list_icon_20.png"))) grid_icon_button = CanvasItem.BitmapButtonCanvasItem(CanvasItem.load_rgba_data_from_bytes(pkgutil.get_data(__name__, "resources/grid_icon_20.png"))) list_icon_button.sizing.set_fixed_size(Geometry.IntSize(20, 20)) grid_icon_button.sizing.set_fixed_size(Geometry.IntSize(20, 20)) button_row = CanvasItem.CanvasItemComposition() button_row.layout = CanvasItem.CanvasItemRowLayout(spacing=4) button_row.add_canvas_item(list_icon_button) button_row.add_canvas_item(grid_icon_button) buttons_widget = ui.create_canvas_widget(properties={"height": 20, "width": 44}) buttons_widget.canvas_item.add_canvas_item(button_row) search_widget = ui.create_row_widget() search_widget.add_spacing(8) search_widget.add(ui.create_label_widget(_("Filter"))) search_widget.add_spacing(8) search_line_edit = ui.create_line_edit_widget() search_line_edit.placeholder_text = _("No Filter") search_line_edit.clear_button_enabled = True # Qt 5.3 doesn't signal text edited or editing finished when clearing. useless so disabled. search_line_edit.on_text_edited = self.document_controller.filter_controller.text_filter_changed search_line_edit.on_editing_finished = self.document_controller.filter_controller.text_filter_changed search_widget.add(search_line_edit) search_widget.add_spacing(6) search_widget.add(buttons_widget) search_widget.add_spacing(8) self.data_view_widget = ui.create_stack_widget() self.data_view_widget.add(data_list_widget) self.data_view_widget.add(data_grid_widget) self.data_view_widget.current_index = 0 self.__view_button_group = CanvasItem.RadioButtonGroup([list_icon_button, grid_icon_button]) self.__view_button_group.current_index = 0 self.__view_button_group.on_current_index_changed = lambda index: setattr(self.data_view_widget, "current_index", index) widget = ui.create_column_widget(properties=properties) widget.add(self.data_view_widget) widget.add_spacing(6) widget.add(search_widget) widget.add_spacing(6) self.widget = widget self._data_list_widget = data_list_widget self._data_grid_widget = data_grid_widget
def __init__(self, event_loop: asyncio.AbstractEventLoop, ui, display_item_adapters_model, selection, direction=GridCanvasItem.Direction.Row, wrap=True): super().__init__() self.__event_loop = event_loop self.__pending_tasks : typing.List = list() self.ui = ui self.__selection = selection self.on_delete_display_item_adapters : typing.Optional[typing.Callable[[typing.List[DisplayItemAdapter]], None]] = None self.on_key_pressed : typing.Optional[typing.Callable[[UserInterface.Key], bool]] = None self.on_display_item_adapter_double_clicked : typing.Optional[typing.Callable[[DisplayItemAdapter], bool]] = None self.on_display_item_adapter_selection_changed : typing.Optional[typing.Callable[[typing.List[DisplayItemAdapter]], None]] = None self.on_context_menu_event : typing.Optional[typing.Callable[[typing.Optional[DisplayItem.DisplayItem], int, int, int, int], bool]] = None self.on_focus_changed : typing.Optional[typing.Callable[[bool], None]] = None self.on_drag_started : typing.Optional[typing.Callable[[UserInterface.MimeData, numpy.ndarray], None]] = None self.__display_item_adapters : typing.List[DisplayItemAdapter] = list() self.__display_item_adapter_needs_update_listeners : typing.List = list() self.__display_item_adapters_model = display_item_adapters_model self.__display_item_adapter_inserted_event_listener = self.__display_item_adapters_model.item_inserted_event.listen(self.__display_item_adapter_inserted) self.__display_item_adapter_removed_event_listener = self.__display_item_adapters_model.item_removed_event.listen(self.__display_item_adapter_removed) self.__display_item_adapter_end_changes_event_listener = self.__display_item_adapters_model.end_changes_event.listen(self.__display_item_adapter_end_changes) class GridCanvasItemDelegate: def __init__(self, data_grid_controller: DataGridController): self.__data_grid_controller = data_grid_controller @property def item_count(self) -> int: return self.__data_grid_controller.display_item_adapter_count @property def items(self) -> typing.List[DisplayItemAdapter]: return self.__data_grid_controller.display_item_adapters def paint_item(self, drawing_context: DrawingContext.DrawingContext, display_item_adapter: DisplayItemAdapter, rect: Geometry.IntRect, is_selected: bool) -> None: display_item_adapter.draw_grid_item(drawing_context, rect) def on_context_menu_event(self, index: int, x: int, y: int, gx: int, gy: int) -> bool: return self.__data_grid_controller.context_menu_event(index, x, y, gx, gy) def on_delete_pressed(self) -> None: self.__data_grid_controller._delete_pressed() def on_key_pressed(self, key: UserInterface.Key) -> bool: return self.__data_grid_controller._key_pressed(key) def on_mouse_double_clicked(self, mouse_index: int, x: int, y: int, modifiers: UserInterface.KeyboardModifiers) -> bool: return self.__data_grid_controller._double_clicked() def on_drag_started(self, index: int, x: int, y: int, modifiers: UserInterface.KeyboardModifiers) -> None: self.__data_grid_controller.drag_started(index, x, y, modifiers) self.icon_view_canvas_item = GridCanvasItem.GridCanvasItem(GridCanvasItemDelegate(self), self.__selection, direction, wrap) def icon_view_canvas_item_focus_changed(focused: bool) -> None: self.icon_view_canvas_item.update() if self.on_focus_changed: self.on_focus_changed(focused) self.icon_view_canvas_item.on_focus_changed = icon_view_canvas_item_focus_changed self.scroll_area_canvas_item = CanvasItem.ScrollAreaCanvasItem(self.icon_view_canvas_item) self.scroll_area_canvas_item.auto_resize_contents = True self.scroll_group_canvas_item = CanvasItem.CanvasItemComposition() if (wrap and direction == GridCanvasItem.Direction.Row) or (not wrap and direction == GridCanvasItem.Direction.Column): self.scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(self.scroll_area_canvas_item) self.scroll_group_canvas_item.layout = CanvasItem.CanvasItemRowLayout() else: self.scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(self.scroll_area_canvas_item, CanvasItem.Orientation.Horizontal) self.scroll_group_canvas_item.layout = CanvasItem.CanvasItemColumnLayout() self.scroll_group_canvas_item.add_canvas_item(self.scroll_area_canvas_item) self.scroll_group_canvas_item.add_canvas_item(self.scroll_bar_canvas_item) """ # dual scroll bars, leave here for easy testing self.vertical_scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(self.scroll_area_canvas_item) self.horizontal_scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(self.scroll_area_canvas_item, CanvasItem.Orientation.Horizontal) self.scroll_group_canvas_item.layout = CanvasItem.CanvasItemGridLayout(Geometry.IntSize(width=2, height=2)) self.scroll_group_canvas_item.add_canvas_item(self.scroll_area_canvas_item, Geometry.IntPoint(x=0, y=0)) self.scroll_group_canvas_item.add_canvas_item(self.vertical_scroll_bar_canvas_item, Geometry.IntPoint(x=1, y=0)) self.scroll_group_canvas_item.add_canvas_item(self.horizontal_scroll_bar_canvas_item, Geometry.IntPoint(x=0, y=1)) """ self.canvas_item = self.scroll_group_canvas_item def selection_changed() -> None: self.selected_indexes = list(self.__selection.indexes) if callable(self.on_display_item_adapter_selection_changed): self.on_display_item_adapter_selection_changed([self.__display_item_adapters[index] for index in list(self.__selection.indexes)]) self.icon_view_canvas_item.make_selection_visible() self.__selection_changed_listener = self.__selection.changed_event.listen(selection_changed) self.selected_indexes = list() # changed display items keep track of items whose content has changed # the content changed messages may come from a thread so have to be # moved to the main thread via this object. self.__changed_display_item_adapters = False self.__changed_display_item_adapters_mutex = threading.RLock() self.__closed = False for index, display_item_adapter in enumerate(self.__display_item_adapters_model.display_item_adapters): self.__display_item_adapter_inserted("display_item_adapters", display_item_adapter, index)
def __init__(self, event_loop: asyncio.AbstractEventLoop, ui: UserInterface.UserInterface, display_item_adapters_model: ListModel.MappedListModel, selection: Selection.IndexedSelection): super().__init__() self.__event_loop = event_loop self.__pending_tasks : typing.List = list() self.ui = ui self.__selection = selection self.on_delete_display_item_adapters : typing.Optional[typing.Callable[[typing.List[DisplayItemAdapter]], None]] = None self.on_key_pressed : typing.Optional[typing.Callable[[UserInterface.Key], bool]] = None self.__display_item_adapters : typing.List[DisplayItemAdapter] = list() self.__display_item_adapter_needs_update_listeners : typing.List = list() self.__display_item_adapters_model = display_item_adapters_model self.__display_item_adapter_inserted_event_listener = self.__display_item_adapters_model.item_inserted_event.listen(self.__display_item_adapter_inserted) self.__display_item_adapter_removed_event_listener = self.__display_item_adapters_model.item_removed_event.listen(self.__display_item_adapter_removed) self.__display_item_adapter_end_changes_event_listener = self.__display_item_adapters_model.end_changes_event.listen(self.__display_item_adapter_end_changes) class ListCanvasItemDelegate: def __init__(self, data_list_controller: DataListController): self.__data_list_controller = data_list_controller @property def item_count(self) -> int: return self.__data_list_controller.display_item_adapter_count @property def items(self) -> typing.List[DisplayItemAdapter]: return self.__data_list_controller.display_item_adapters def paint_item(self, drawing_context: DrawingContext.DrawingContext, display_item_adapter: DisplayItemAdapter, rect: Geometry.IntRect, is_selected: bool) -> None: display_item_adapter.draw_list_item(drawing_context, rect) def context_menu_event(self, index: int, x: int, y: int, gx: int, gy: int) -> bool: return self.__data_list_controller.context_menu_event(index, x, y, gx, gy) def delete_pressed(self) -> None: self.__data_list_controller._delete_pressed() def key_pressed(self, key: UserInterface.Key) -> bool: return self.__data_list_controller._key_pressed(key) def drag_started(self, index: int, x: int, y: int, modifiers: UserInterface.KeyboardModifiers) -> None: self.__data_list_controller.drag_started(index, x, y, modifiers) self.__list_canvas_item = ListCanvasItem.ListCanvasItem(ListCanvasItemDelegate(self), self.__selection) def focus_changed(focused: bool) -> None: self.__list_canvas_item.update() if self.on_focus_changed: self.on_focus_changed(focused) self.__list_canvas_item.on_focus_changed = focus_changed self.scroll_area_canvas_item = CanvasItem.ScrollAreaCanvasItem(self.__list_canvas_item) self.scroll_area_canvas_item.auto_resize_contents = True self.scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(self.scroll_area_canvas_item) self.scroll_group_canvas_item = CanvasItem.CanvasItemComposition() self.scroll_group_canvas_item.layout = CanvasItem.CanvasItemRowLayout() self.scroll_group_canvas_item.add_canvas_item(self.scroll_area_canvas_item) self.scroll_group_canvas_item.add_canvas_item(self.scroll_bar_canvas_item) self.canvas_item = self.scroll_group_canvas_item def selection_changed() -> None: self.selected_indexes = list(self.__selection.indexes) if callable(self.on_display_item_adapter_selection_changed): self.on_display_item_adapter_selection_changed([self.__display_item_adapters[index] for index in list(self.__selection.indexes)]) self.__list_canvas_item.make_selection_visible() self.__selection_changed_listener = self.__selection.changed_event.listen(selection_changed) self.selected_indexes = list() self.on_display_item_adapter_selection_changed : typing.Optional[typing.Callable[[typing.List[DisplayItemAdapter]], None]] = None self.on_context_menu_event : typing.Optional[typing.Callable[[typing.Optional[DisplayItem.DisplayItem], int, int, int, int], bool]] = None self.on_focus_changed : typing.Optional[typing.Callable[[bool], None]] = None self.on_drag_started : typing.Optional[typing.Callable[[UserInterface.MimeData, numpy.ndarray], None]] = None # changed display items keep track of items whose content has changed # the content changed messages may come from a thread so have to be # moved to the main thread via this object. self.__changed_display_item_adapters = False self.__changed_display_item_adapters_mutex = threading.RLock() for index, display_item_adapter in enumerate(self.__display_item_adapters_model.display_item_adapters): self.__display_item_adapter_inserted("display_item_adapters", display_item_adapter, index)
def __init__(self, ui: UserInterface.UserInterface, list_item_delegate: ListCanvasItem.ListCanvasItemDelegate, *, items: typing.Optional[typing.Sequence[typing.Any]] = None, selection_style: typing.Optional[Selection.Style] = None, properties: typing.Optional[typing.Mapping[ str, typing.Any]] = None, selection: typing.Optional[Selection.IndexedSelection] = None, border_color: typing.Optional[str] = None, v_scroll_enabled: bool = True, v_auto_resize: bool = False) -> None: column_widget = ui.create_column_widget() super().__init__(column_widget) self.property_changed_event = Event.Event() items = items or list() self.__items: typing.List[typing.Any] = list() self.on_selection_changed: typing.Optional[typing.Callable[ [typing.AbstractSet[int]], None]] = None self.on_item_selected: typing.Optional[typing.Callable[[int], bool]] = None self.on_cancel: typing.Optional[typing.Callable[[], None]] = None self.on_item_handle_context_menu: typing.Optional[typing.Callable[ ..., bool]] = None # used for declarative self.__items_binding: typing.Optional[Binding.Binding] = None self.__current_index_binding: typing.Optional[Binding.Binding] = None self.__on_current_index_changed: typing.Optional[typing.Callable[ [int], None]] = None self.__v_auto_resize = v_auto_resize self.on_escape_pressed: typing.Optional[typing.Callable[[], bool]] = None self.on_return_pressed: typing.Optional[typing.Callable[[], bool]] = None self.__selection = selection if selection else Selection.IndexedSelection( selection_style) def selection_changed() -> None: on_selection_changed = self.on_selection_changed if callable(on_selection_changed): on_selection_changed(self.__selection.indexes) if callable(self.__on_current_index_changed): self.__on_current_index_changed(self.current_index) def handle_delegate_cancel() -> None: if callable(self.on_cancel): self.on_cancel() if callable(self.on_escape_pressed): self.on_escape_pressed() def handle_delegate_item_selected(index: int) -> None: if callable(self.on_item_selected): self.on_item_selected(index) if callable(self.on_return_pressed): self.on_return_pressed() self.__selection_changed_event_listener = self.__selection.changed_event.listen( selection_changed) self.__list_canvas_item_delegate = list_item_delegate self.__list_canvas_item_delegate.on_cancel = handle_delegate_cancel self.__list_canvas_item_delegate.on_item_selected = handle_delegate_item_selected self.__list_canvas_item = ListCanvasItem.ListCanvasItem( self.__list_canvas_item_delegate, self.__selection, 20) scroll_area_canvas_item = CanvasItem.ScrollAreaCanvasItem( self.__list_canvas_item) scroll_area_canvas_item.auto_resize_contents = True scroll_group_canvas_item = CanvasItem.CanvasItemComposition() if border_color is not None: scroll_group_canvas_item.border_color = border_color scroll_group_canvas_item.layout = CanvasItem.CanvasItemRowLayout() scroll_group_canvas_item.add_canvas_item(scroll_area_canvas_item) if v_scroll_enabled: scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem( scroll_area_canvas_item) scroll_group_canvas_item.add_canvas_item(scroll_bar_canvas_item) canvas_widget = ui.create_canvas_widget(properties=properties) canvas_widget.canvas_item.add_canvas_item(scroll_group_canvas_item) column_widget.add(canvas_widget) self.__canvas_widget = canvas_widget self.items = list(items)
def __init__(self, ui, app=None): super().__init__(ui, app) hello_world_str_ref = [ "Hello World!", ] # place the hello world text into a row so that the text can be left justified within the row # by adding a stretch on the right side of the row. then configure the height of the row to match # the height of the hello world text. # make a column in which to place the hello world text and a custom canvas item, add the items, # then add stretch at the bottom so that the fixed height items get pushed to the top. progress_bar_row = CanvasItem.CanvasItemComposition() progress_bar_row.layout = CanvasItem.CanvasItemRowLayout(spacing=4) progress_bar_canvas_item = CanvasItem.ProgressBarCanvasItem() progress_bar_canvas_item.progress = 0 progress_bar_canvas_item.sizing.set_fixed_width(500) progress_bar_row.add_canvas_item(progress_bar_canvas_item) progress_bar_row.add_stretch() progress_bar_row.sizing.set_fixed_height( progress_bar_canvas_item.sizing.preferred_height) check_box_row = CanvasItem.CanvasItemComposition() check_box_row.layout = CanvasItem.CanvasItemRowLayout(spacing=4) check_box_canvas_item = CanvasItem.CheckBoxCanvasItem() check_box_canvas_item.sizing.set_fixed_width(20) check_box_canvas_item.sizing.set_fixed_height(20) check_box_row.add_canvas_item(check_box_canvas_item) check_box_row.add_stretch() check_box_row.sizing.set_fixed_height(20) column_canvas_item = CanvasItem.CanvasItemComposition() column_canvas_item.layout = CanvasItem.CanvasItemColumnLayout( spacing=12, alignment="start") brown_square_row = CanvasItem.CanvasItemComposition() brown_square_row.layout = CanvasItem.CanvasItemRowLayout(spacing=4) brown_square_canvas_item = BrownSquareCanvasItem() brown_square_row.add_canvas_item(brown_square_canvas_item) brown_square_row.add_stretch() brown_square_row.sizing.set_fixed_height( brown_square_canvas_item.sizing.preferred_height) column_canvas_item.add_canvas_item(brown_square_row) column_canvas_item.add_canvas_item(progress_bar_row) column_canvas_item.add_canvas_item(check_box_row) column_canvas_item.add_stretch() # configure what happens when the button is pressed click_count_ref = [0] def button_clicked(): click_count_ref[0] += 1 hello_widget.text = hello_world_str_ref[0] + " (" + str( click_count_ref[0]) + ")" progress_bar_canvas_item.progress += 0.1 def checked_changed(value): hello_world_str_ref[ 0] = "Goodbye World..." if value else "Hello World!" button_clicked() # finally add the column to a root widget and attach the root widget to the document window. root_widget = ui.create_column_widget(alignment="start") one_row = ui.create_row_widget() one_row.add_stretch() one_row.add(ui.create_label_widget("Centered")) one_row.add_stretch() check_box_widget = ui.create_check_box_widget("Check BOX") hello_widget = ui.create_push_button_widget(hello_world_str_ref[0]) canvas_widget = ui.create_canvas_widget(properties={ "height": 500, "width": 600 }) canvas_widget.canvas_item.add_canvas_item(column_canvas_item) root_widget.add(one_row) root_widget.add(check_box_widget) root_widget.add(hello_widget) root_widget.add(canvas_widget) self.attach_widget(root_widget) hello_widget.on_clicked = button_clicked check_box_widget.on_checked_changed = checked_changed
def __init__( self, event_loop: asyncio.AbstractEventLoop, ui: UserInterface.UserInterface, canvas_item: CanvasItem.AbstractCanvasItem, display_item_adapters_model: ListModel.MappedListModel, selection: Selection.IndexedSelection, direction: GridCanvasItem.Direction = GridCanvasItem.Direction.Row, wrap: bool = True) -> None: self.__event_loop = event_loop self.__pending_tasks: typing.List[asyncio.Task[None]] = list() self.ui = ui self.__selection = selection self.__display_item_adapters: typing.List[DisplayItemAdapter] = list() self.__display_item_adapter_needs_update_listeners: typing.List[ Event.EventListener] = list() self.__display_item_adapters_model = display_item_adapters_model self.__display_item_adapter_inserted_event_listener = self.__display_item_adapters_model.item_inserted_event.listen( self.__display_item_adapter_inserted) self.__display_item_adapter_removed_event_listener = self.__display_item_adapters_model.item_removed_event.listen( self.__display_item_adapter_removed) self.__display_item_adapter_end_changes_event_listener = self.__display_item_adapters_model.end_changes_event.listen( self.__display_item_adapter_end_changes) self.on_delete_display_item_adapters: typing.Optional[typing.Callable[ [typing.List[DisplayItemAdapter]], None]] = None self.on_key_pressed: typing.Optional[typing.Callable[ [UserInterface.Key], bool]] = None self.on_display_item_adapter_double_clicked: typing.Optional[ typing.Callable[[DisplayItemAdapter], bool]] = None self.on_context_menu_event: typing.Optional[typing.Callable[[ typing.Optional[DisplayItem.DisplayItem], typing. List[DisplayItem.DisplayItem], int, int, int, int ], bool]] = None self.on_focus_changed: typing.Optional[typing.Callable[[bool], None]] = None self.on_drag_started: typing.Optional[typing.Callable[ [UserInterface.MimeData, typing.Optional[_NDArray]], None]] = None # changed display items keep track of items whose content has changed # the content changed messages may come from a thread so have to be # moved to the main thread via this object. self.__changed_display_item_adapters = False self.__changed_display_item_adapters_mutex = threading.RLock() self.__list_canvas_item = canvas_item def focus_changed(focused: bool) -> None: self.__list_canvas_item.update() if self.on_focus_changed: self.on_focus_changed(focused) self.__list_canvas_item.on_focus_changed = focus_changed self.scroll_area_canvas_item = CanvasItem.ScrollAreaCanvasItem( self.__list_canvas_item) self.scroll_area_canvas_item.auto_resize_contents = True self.scroll_group_canvas_item = CanvasItem.CanvasItemComposition() if (wrap and direction == GridCanvasItem.Direction.Row) or ( not wrap and direction == GridCanvasItem.Direction.Column): self.scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem( self.scroll_area_canvas_item) self.scroll_group_canvas_item.layout = CanvasItem.CanvasItemRowLayout( ) else: self.scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem( self.scroll_area_canvas_item, CanvasItem.Orientation.Horizontal) self.scroll_group_canvas_item.layout = CanvasItem.CanvasItemColumnLayout( ) self.scroll_group_canvas_item.add_canvas_item( self.scroll_area_canvas_item) self.scroll_group_canvas_item.add_canvas_item( self.scroll_bar_canvas_item) """ # dual scroll bars, leave here for easy testing self.vertical_scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(self.scroll_area_canvas_item) self.horizontal_scroll_bar_canvas_item = CanvasItem.ScrollBarCanvasItem(self.scroll_area_canvas_item, CanvasItem.Orientation.Horizontal) self.scroll_group_canvas_item.layout = CanvasItem.CanvasItemGridLayout(Geometry.IntSize(width=2, height=2)) self.scroll_group_canvas_item.add_canvas_item(self.scroll_area_canvas_item, Geometry.IntPoint(x=0, y=0)) self.scroll_group_canvas_item.add_canvas_item(self.vertical_scroll_bar_canvas_item, Geometry.IntPoint(x=1, y=0)) self.scroll_group_canvas_item.add_canvas_item(self.horizontal_scroll_bar_canvas_item, Geometry.IntPoint(x=0, y=1)) """ self.__canvas_item = self.scroll_group_canvas_item def selection_changed() -> None: self.selected_indexes = list(self.__selection.indexes) typing.cast(ItemExplorerCanvasItemLike, self.__list_canvas_item).make_selection_visible() self.__selection_changed_listener: typing.Optional[ Event.EventListener] = self.__selection.changed_event.listen( selection_changed) self.selected_indexes = list() for index, display_item_adapter in enumerate( self.__display_item_adapters_model.display_item_adapters): self.__display_item_adapter_inserted("display_item_adapters", display_item_adapter, index) self.__closed = False