def __init__(self, cursor_changed_fn: typing.Callable[[float], None]): super().__init__() # tell the canvas item that we want mouse events. self.wants_mouse_events = True # create the component canvas items: adornments and the graph. self.__adornments_canvas_item = AdornmentsCanvasItem() self.__simple_line_graph_canvas_item = SimpleLineGraphCanvasItem() self.__histogram_color_map_canvas_item = ColorMapCanvasItem() # canvas items get added back to front column = CanvasItem.CanvasItemComposition() column.layout = CanvasItem.CanvasItemColumnLayout() graph_and_adornments = CanvasItem.CanvasItemComposition() graph_and_adornments.add_canvas_item( self.__simple_line_graph_canvas_item) graph_and_adornments.add_canvas_item(self.__adornments_canvas_item) column.add_canvas_item(graph_and_adornments) column.add_canvas_item(self.__histogram_color_map_canvas_item) self.add_canvas_item(column) # used for mouse tracking. self.__pressed = False self.on_set_display_limits = None self.__cursor_changed = cursor_changed_fn
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, document_controller: DocumentController.DocumentController, panel_id: str, properties: typing.Mapping[str, typing.Any]) -> None: super().__init__(document_controller, panel_id, _("Metadata")) ui = self.ui self.__metadata_model = MetadataModel(document_controller) delegate = MetadataEditorTreeDelegate(dict()) metadata_editor_widget = ui.create_canvas_widget() metadata_editor_canvas_item = TreeCanvasItem.TreeCanvasItem( ui.get_font_metrics, delegate) metadata_editor_widget.canvas_item.layout = CanvasItem.CanvasItemColumnLayout( ) metadata_editor_widget.canvas_item.add_canvas_item( metadata_editor_canvas_item) metadata_editor_widget.canvas_item.add_stretch() self.__metadata_editor_canvas_item = metadata_editor_canvas_item column = self.ui.create_column_widget() column.add_spacing(6) column.add(metadata_editor_widget) column.add_spacing(6) scroll_area = self.ui.create_scroll_area_widget() scroll_area.set_scrollbar_policies("needed", "needed") scroll_area.content = column def content_height_changed(content_height: int) -> None: desired_height = content_height + 12 metadata_editor_canvas_item.update_sizing( metadata_editor_canvas_item.sizing.with_fixed_height( desired_height)) metadata_editor_widget.canvas_item.update_layout( Geometry.IntPoint(), scroll_area.size) if metadata_editor_canvas_item._has_layout: column.size = Geometry.IntSize(height=desired_height, width=column.size.width) metadata_editor_canvas_item.on_content_height_changed = content_height_changed def metadata_changed(metadata: DataAndMetadata.MetadataType) -> None: delegate.metadata = metadata def reconstruct_metadata() -> None: if self.__metadata_editor_canvas_item: # use this instead of local variable to handle close properly self.__metadata_editor_canvas_item.reconstruct() self.document_controller.queue_task(reconstruct_metadata) self.__metadata_changed_event_listener = self.__metadata_model.metadata_changed_event.listen( metadata_changed) self.widget = scroll_area
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, 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