def __init__(self, parent_window: Window.Window, ui_widget: Declarative.UIDescription, ui_handler: Declarative.HandlerLike) -> None: super().__init__(parent_window.ui, app=parent_window.app, parent_window=parent_window, window_style="popup") from nion.ui import Declarative # avoid circular reference def request_close() -> None: # this may be called in response to the user clicking a button to close. # make sure that the button is not destructed as a side effect of closing # the window by queueing the close. and it is not possible to use event loop # here because the event loop limitations: not able to run both parent and child # event loops simultaneously. parent_window.queue_task(self.request_close) # make and attach closer for the handler; put handler into container closer self.__closer = Declarative.Closer() if ui_handler and hasattr(ui_handler, "close"): setattr(ui_handler, "_closer", Declarative.Closer()) self.__closer.push_closeable(ui_handler) finishes: typing.List[typing.Callable[[], None]] = list() self.widget = Declarative.construct(parent_window.ui, self, ui_widget, ui_handler, finishes) self.attach_widget(self.widget) for finish in finishes: finish() if ui_handler and hasattr(ui_handler, "init_handler"): getattr(ui_handler, "init_handler")() if ui_handler and hasattr(ui_handler, "init_popup"): getattr(ui_handler, "init_popup")(request_close) self.__ui_handler = ui_handler
def main(args, bootstrap_args): ui = Declarative.DeclarativeUI() button = ui.create_push_button(text=_("Hello World"), on_clicked="button_clicked") label = ui.create_label(name="label_item", text=_("Not Clicked")) column = ui.create_column(button, label, spacing=8) window = ui.create_window(column, title=_("Hello World"), margin=12) handler = Handler() return Declarative.run_ui(args, bootstrap_args, window, handler)
def build(self, ui: UserInterface.UserInterface, event_loop: asyncio.AbstractEventLoop, **kwargs: typing.Any) -> Declarative.DeclarativeWidget: u = Declarative.DeclarativeUI() class Handler(Declarative.HandlerLike): def __init__(self, ui_view: Declarative.UIDescription) -> None: self.ui_view = ui_view def close(self) -> None: pass no_content_row = u.create_row(u.create_stretch(), u.create_label(text=_("No Preferences Available")), u.create_stretch()) content = u.create_column(no_content_row) return Declarative.DeclarativeWidget(ui, event_loop, Handler(content))
def resources(self): u = Declarative.DeclarativeUI() driver_display_name_label = u.create_label(text="@binding(driver_display_name)") device_id_field = u.create_line_edit(text="@binding(settings.device_id)", width=180) display_name_field = u.create_line_edit(text="@binding(settings.name)", width=240) edit_group_content = u.create_component_instance("edit_group") edit_group = u.create_group(edit_group_content, margin=8) edit_row = u.create_row(edit_group, u.create_stretch()) apply_button = u.create_push_button(name="apply_button", text=_("Apply"), on_clicked="apply") revert_button = u.create_push_button(name="revert_button", text=_("Revert"), on_clicked="revert") remove_button = u.create_push_button(text=_("Remove"), on_clicked="remove") remove_row = u.create_row(apply_button, revert_button, remove_button, u.create_stretch()) label_column = u.create_column(u.create_label(text=_("Driver:")), u.create_label(text=_("Device ID:")), u.create_label(text=_("Display Name:")), spacing=4) field_column = u.create_column(driver_display_name_label, device_id_field, display_name_field, spacing=4) content_row = u.create_row(label_column, field_column, u.create_stretch(), spacing=12) content = u.create_column(content_row, edit_row, remove_row, spacing=8) component = u.define_component(content=content, component_id="section") return {"section": component}
def __init__(self, notification: Notification.Notification) -> None: self.notification = notification u = Declarative.DeclarativeUI() self.ui_view = u.create_row( u.create_column( u.create_row( u.create_label(text="@binding(notification.task_name)", color="#3366CC"), u.create_stretch(), {"type": "notification_char_button", "text": " \N{MULTIPLICATION X} ", "on_clicked": "handle_dismiss"}, spacing=8 ), u.create_row( u.create_label(text="@binding(notification.title)", font="bold"), u.create_stretch(), spacing=8 ), u.create_row( u.create_label(text="@binding(notification.text)", word_wrap=True, width=440), u.create_stretch(), spacing=8 ), u.create_divider(orientation="horizontal"), spacing=4, ), )
def get_ui(self, version): actual_version = "1.0.0" if Utility.compare_versions(version, actual_version) > 0: raise NotImplementedError( "API requested version %s is greater than %s." % (version, actual_version)) return Declarative.DeclarativeUI()
def resources(self) -> typing.Mapping[str, typing.Any]: ui = Declarative.DeclarativeUI() field_label = ui.create_label(name="label_widget") field_line_edit = ui.create_line_edit(name="value_widget", on_editing_finished="value_changed") field = ui.create_row(field_label, field_line_edit, ui.create_stretch(), spacing=8) field_events = [{"event": "on_value_changed", "parameters": ["value"]}] field_component = ui.define_component(content=field, events=field_events) return {"field": field_component}
def __init__( self, document_controller: DocumentController.DocumentController ) -> None: self.document_controller = document_controller activities = ListModel.ListModel[Activity.Activity]() stack_index = Model.PropertyModel[int](0) def activity_appended(activity: Activity.Activity) -> None: async def append_activity(activity: Activity.Activity) -> None: activities.append_item(activity) document_controller.event_loop.create_task( append_activity(activity)) def activity_finished(activity: Activity.Activity) -> None: async def finish_activity(activity: Activity.Activity) -> None: activities.remove_item(activities.items.index(activity)) document_controller.event_loop.create_task( finish_activity(activity)) self.__activity_appended_listener = Activity.activity_appended_event.listen( activity_appended) self.__activity_finished_listener = Activity.activity_finished_event.listen( activity_finished) self.activities = activities self.stack_index = stack_index def activity_changed(key: str, value: Activity.Activity, index: int) -> None: stack_index.value = 1 if len(activities.items) > 0 else 0 self.__activity_inserted_listener = self.activities.item_inserted_event.listen( activity_changed) self.__activity_removed_listener = self.activities.item_removed_event.listen( activity_changed) u = Declarative.DeclarativeUI() self.ui_view = u.create_column( u.create_label(text=_("** Activity Panel is Beta **"), color="darkred", font="bold"), u.create_stack(u.create_column( u.create_label(text=_("No activities.")), u.create_stretch(), ), u.create_column( u.create_column(items="activities.items", item_component_id="activity", spacing=6), u.create_stretch(), ), current_index="@binding(stack_index.value)"), u.create_stretch(), spacing=8, margin=8)
def __init__(self, document_controller: DocumentController.DocumentController, panel_id: str, properties: typing.Mapping[str, typing.Any]) -> None: super().__init__(document_controller, panel_id, _("Activity")) activity_controller = ActivityController(document_controller) self.widget = Declarative.DeclarativeWidget( document_controller.ui, document_controller.event_loop, activity_controller)
def __init__(self, activity: Activity.Activity) -> None: self.activity = activity u = Declarative.DeclarativeUI() self.ui_view = u.create_row(u.create_label( text="@binding(activity.displayed_title)", word_wrap=True, width=296), u.create_stretch(), spacing=8)
def main( args: typing.Sequence[typing.Any], bootstrap_args: typing.Mapping[str, typing.Any] ) -> Application.BaseApplication: u = Declarative.DeclarativeUI() page_list = [ (Buttons, "buttons", _("Buttons")), (CheckBoxes, "check_boxes", _("Check Boxes")), (ComboBoxes, "combo_boxes", _("Combo Boxes")), (Bindings, "bindings", _("Bindings")), (Compositions, "compositions", _("Compositions")), (Converters, "converters", _("Converters")), (Groups, "groups", _("Groups")), (LineEdits, "line_edits", _("Line Edits")), (ProgressBars, "progress_bars", _("Progress Bars")), (RadioButtons, "radio_buttons", _("Radio Buttons")), (Sliders, "sliders", _("Sliders")), (Stacks, "stacks", _("Stacks")), (StatusBar, "status_bar", _("Status Bar")), (Tabs, "tabs", _("Tabs")), (ComponentLayout, "component_layout", _("Component Layout")), (ComponentStack, "component_stack", _("Component Stack")), (ComponentContent, "component_content", _("Component Content")), (ComponentPolymorphic, "component_polymorphic", _("Component Polymorphic")), ] handler = Handler(page_list) resources = dict() pages = list() items = list() for page_cls, page_id, page_title in page_list: resources[page_id] = u.define_component( content=typing.cast(typing.Any, page_cls).construct_ui(u)) instance = u.create_component_instance(page_id) pages.append(u.create_column(instance, u.create_stretch())) items.append(page_title) chooser_combo_box = u.create_combo_box( items=items, on_current_index_changed="select_page") page_stack = u.create_stack(*pages, name="page_stack") page_group = u.create_group(page_stack, margin=8) main_column = u.create_column(chooser_combo_box, page_group, spacing=8) window = u.create_window(main_column, title=_("UI Demo"), margin=12, resources=resources) return Application.run_window(args, bootstrap_args, window, handler)
def __init__(self, actions: typing.Sequence[Window.Action], document_controller: DocumentController.DocumentController, **kwargs: typing.Any) -> None: self.__document_controller = document_controller u = Declarative.DeclarativeUI() top_row = [self.__create_action_button(actions[i]) for i in range(0, len(actions), 2)] bottom_row = [self.__create_action_button(actions[i]) for i in range(1, len(actions), 2)] self.ui_view = u.create_column(u.create_spacing(4), u.create_row(*top_row), u.create_row(*bottom_row), u.create_spacing(4), u.create_stretch())
def __init__(self, document_controller: DocumentController.DocumentController, panel_id: str, properties: Persistence.PersistentDictType) -> None: super().__init__(document_controller, panel_id, _("Toolbar")) self.__component_registered_listener = Registry.listen_component_registered_event(self.__component_registered) self.widget = self.ui.create_column_widget() # note: "maximum" here means the size hint is maximum and the widget can be smaller. Qt layout is atrocious. self.__toolbar_widget_row = self.ui.create_row_widget(properties={"size-policy-horizontal": "maximum"}) toolbar_row_widget = self.ui.create_row_widget() toolbar_row_widget.add(self.__toolbar_widget_row) toolbar_row_widget.add_stretch() self.widget.add(toolbar_row_widget) # make a map from widget_id to widget factory. widget_factories = dict() for component in Registry.get_components_by_type("toolbar-widget"): widget_factories[component.toolbar_widget_id] = component # define the order of widgets. # this part is hard coded for now; needs some work to make it dynamically order widgets as they become # available from packages. widget_id_list = [ "nion.swift.toolbar-widget.tool-mode", "nion.swift.toolbar-widget.raster-zoom", "nion.swift.toolbar-widget.workspace" ] # add the widgets. for widget_id in widget_id_list: widget_factory = widget_factories[widget_id] widget_handler = widget_factory(document_controller=self.document_controller) widget = Declarative.DeclarativeWidget(self.ui, self.document_controller.event_loop, widget_handler) widget_section = self.ui.create_row_widget() widget_section.add(widget) section_bar = self.ui.create_canvas_widget(properties={"width": 9, "size_policy_vertical": "expanding"}) def draw(drawing_context: DrawingContext.DrawingContext, canvas_size: Geometry.IntSize, *args: typing.Any, **kwargs: typing.Any) -> None: with drawing_context.saver(): drawing_context.rect(0, 0, canvas_size.width, canvas_size.height) drawing_context.fill_style = "#DDD" drawing_context.stroke_style = "#AAA" drawing_context.fill() drawing_context.stroke() section_bar.canvas_item.add_canvas_item(CanvasItem.DrawCanvasItem(draw)) self.__toolbar_widget_row.add(section_bar) self.__toolbar_widget_row.add_spacing(8) self.__toolbar_widget_row.add(widget_section) self.__toolbar_widget_row.add_spacing(8) end_divider = self.ui.create_canvas_widget(properties={"width": 1, "size_policy_vertical": "expanding"}) end_divider.canvas_item.add_canvas_item(CanvasItem.DividerCanvasItem(color="#888")) self.__toolbar_widget_row.add(end_divider)
def __init__(self, *, document_controller: DocumentController.DocumentController, **kwargs: typing.Any) -> None: self.radio_button_value: Model.PropertyModel[int] = Model.PropertyModel(0) u = Declarative.DeclarativeUI() top_row_items = list() bottom_row_items = list() modes = list() tool_actions = list() for action in Window.actions.values(): if action.action_id.startswith("window.set_tool_mode"): tool_actions.append(typing.cast(DocumentController.SetToolModeAction, action)) for i, tool_action in enumerate(tool_actions): tool_id = tool_action.tool_mode icon_png = tool_action.tool_icon tool_tip = tool_action.tool_tip key_shortcut = Window.action_shortcuts.get(tool_action.action_id, dict()).get("display_panel", None) if key_shortcut: tool_tip += f" ({key_shortcut})" modes.append(tool_id) assert icon_png is not None icon_data = CanvasItem.load_rgba_data_from_bytes(icon_png) icon_property = "icon_" + tool_id setattr(self, icon_property, icon_data) radio_button = u.create_radio_button(icon=f"@binding({icon_property})", value=i, group_value="@binding(radio_button_value.value)", width=32, height=24, tool_tip=tool_tip) if i % 2 == 0: top_row_items.append(radio_button) else: bottom_row_items.append(radio_button) top_row = u.create_row(*top_row_items) bottom_row = u.create_row(*bottom_row_items) self.ui_view = u.create_row(u.create_column(u.create_spacing(4), top_row, bottom_row, u.create_spacing(4), u.create_stretch())) self.radio_button_value.value = modes.index(document_controller.tool_mode) def tool_mode_changed(tool_mode: str) -> None: self.radio_button_value.value = modes.index(tool_mode) self.__tool_mode_changed_event_listener = document_controller.tool_mode_changed_event.listen(tool_mode_changed) tool_mode_changed(document_controller.tool_mode) def radio_button_changed(property: str) -> None: if property == "value": mode_index = self.radio_button_value.value if mode_index is not None: document_controller.tool_mode = modes[mode_index] self.__radio_button_value_listener = self.radio_button_value.property_changed_event.listen(radio_button_changed)
def main( args: typing.Sequence[typing.Any], bootstrap_args: typing.Mapping[str, typing.Any] ) -> Application.BaseApplication: ui = Declarative.DeclarativeUI() button = ui.create_push_button(text=_("Hello World"), on_clicked="button_clicked") label = ui.create_label(name="label_item", text=_("Not Clicked")) column = ui.create_column(button, label, spacing=8) window = ui.create_window(column, title=_("Hello World"), margin=12) return Application.run_window(args, bootstrap_args, window, Handler())
def resources(self) -> typing.Mapping[str, typing.Any]: # when a new mode is added to the model.modes structured array, the stack will create a new child to # display/edit the new mode. the declarative UI for the new child is returned here under the "mode" key which is # the same as the "item_component_id" passed to "create_stack". the handler for the new child is returned in # "create_handler". u = Declarative.DeclarativeUI() title_label = u.create_label(name="title_label_widget") balance_field = u.create_line_edit(text="@binding(mode.balance, converter=balance_converter)") remove_button = u.create_push_button(text="X", on_clicked="remove") row = u.create_row(title_label, balance_field, remove_button, u.create_stretch(), spacing=8) component = u.define_component(content=row) return {"mode": component}
def __init__(self, document_controller: DocumentController.DocumentController, panel_id: str, properties: dict): super().__init__(document_controller, panel_id, 'libertem-panel') panel_type = properties.get('panel_type') for component in Registry.get_components_by_type('libertem-panel'): if component.panel_type == panel_type: ui_handler = component.get_ui_handler( api_broker=PlugInManager.APIBroker(), event_loop=document_controller.event_loop) self.widget = Declarative.DeclarativeWidget( document_controller.ui, document_controller.event_loop, ui_handler)
def show_ok_dialog( self, title: str, message: str, *, completion_fn: typing.Optional[typing.Callable[[], None]] = None) -> None: u = Declarative.DeclarativeUI() error_message = u.create_label(text=message) button_row = u.create_row( u.create_stretch(), u.create_push_button(text=_("OK"), on_clicked="close_window")) main_column = u.create_column(error_message, button_row, spacing=8, width=300) window = u.create_window(main_column, title=title, margin=12, window_style="tool") Declarative.WindowHandler(completion_fn=completion_fn).run(window, app=self)
def get_resource(self, resource_id: str, container: typing.Optional[typing.Any] = None, item: typing.Any = None) -> typing.Optional[Declarative.UIDescription]: u = Declarative.DeclarativeUI() if resource_id == "rectangle": width_row = u.create_row(u.create_label(text="Width:"), u.create_label(text="@binding(shape.width)"), spacing=8) height_row = u.create_row(u.create_label(text="Height:"), u.create_label(text="@binding(shape.height)"), spacing=8) return u.define_component(u.create_group(u.create_column(width_row, height_row, spacing=8), title="@binding(shape.label)")) elif resource_id == "circle": radius_row = u.create_row(u.create_label(text="Radius:"), u.create_label(text="@binding(shape.radius)"), spacing=8) return u.define_component(u.create_group(u.create_column(radius_row, spacing=8), title="@binding(shape.label)")) elif resource_id == "interval": left_row = u.create_row(u.create_label(text="Left:"), u.create_label(text="@binding(shape.left)"), spacing=8) right_row = u.create_row(u.create_label(text="Right:"), u.create_label(text="@binding(shape.right)"), spacing=8) return u.define_component(u.create_group(u.create_column(left_row, right_row, spacing=8), title="@binding(shape.label)")) return None
def show_ok_cancel_dialog( self, title: str, message: str, *, ok_text: str = None, cancel_text: str = None, completion_fn: typing.Optional[typing.Callable[[bool], None]] = None ) -> None: u = Declarative.DeclarativeUI() error_message = u.create_label(text=message) button_row = u.create_row( u.create_stretch(), u.create_push_button(text=cancel_text or _("Cancel"), on_clicked="handle_reject"), u.create_push_button(text=ok_text or _("OK"), on_clicked="handle_accept"), spacing=12) main_column = u.create_column(error_message, button_row, spacing=8, width=380) window = u.create_window(main_column, title=title, margin=12, window_style="tool") class OkCancelHandler(Declarative.WindowHandler): def __init__(self): super().__init__(completion_fn=self.handle_close) self.__result = False def handle_close(self) -> None: if callable(completion_fn): completion_fn(self.__result) def handle_accept( self, widget: typing.Optional[Declarative.UIWidget]) -> None: self.__result = True self.close_window(widget) def handle_reject( self, widget: typing.Optional[Declarative.UIWidget]) -> None: self.__result = False self.close_window(widget) OkCancelHandler().run(window, app=self)
def __init__(self, parent_window: Window.Window, ui_widget: Declarative.UIDescription, ui_handler): super().__init__(parent_window.ui, app=parent_window.app, parent_window=parent_window, window_style="popup") def request_close(): # this may be called in response to the user clicking a button to close. # make sure that the button is not destructed as a side effect of closing # the window by queueing the close. and it is not possible to use event loop # here because the event loop limitations: not able to run both parent and child # event loops simultaneously. parent_window.queue_task(self.request_close) # make and attach closer for the handler; put handler into container closer self.__closer = Declarative.Closer() if ui_handler and hasattr(ui_handler, "close"): ui_handler._closer = Declarative.Closer() self.__closer.push_closeable(ui_handler) finishes = list() self.widget = Declarative.construct(parent_window.ui, self, ui_widget, ui_handler, finishes) self.attach_widget(self.widget) for finish in finishes: finish() if ui_handler and hasattr(ui_handler, "init_handler"): ui_handler.init_handler() if ui_handler and hasattr(ui_handler, "init_popup"): ui_handler.init_popup(request_close) # TODO: select all works, but edit commands don't work # TODO: tabs don't work self._create_menus() self.__ui_handler = ui_handler
def resources(self) -> typing.Mapping[str, typing.Any]: ui = Declarative.DeclarativeUI() title_label = ui.create_label(name="title_label_widget") count_label = ui.create_label(name="count_label_widget") increase_button = ui.create_push_button(text="++", on_clicked="increase_count") decrease_button = ui.create_push_button(text="--", on_clicked="decrease_count") remove_button = ui.create_push_button(text="X", on_clicked="remove") row = ui.create_row(title_label, count_label, increase_button, decrease_button, remove_button, ui.create_stretch(), spacing=8) component = ui.define_component(content=row) return {"section": component}
def get_editor_description(self): u = Declarative.DeclarativeUI() camera_names = [ cam.get('product', cam.get('serial')) for cam in self.available_cameras ] camera_index_combo = u.create_combo_box( items=camera_names, current_index="@binding(camera_index_model.value)") label_column = u.create_column( u.create_label(text=_("Select camera from list:")), spacing=4) field_column = u.create_column(camera_index_combo, spacing=4) return u.create_row(label_column, field_column, u.create_stretch(), spacing=12)
def get_editor_description(self): u = Declarative.DeclarativeUI() url_field = u.create_line_edit(text="@binding(settings.url)", width=360) camera_index_combo = u.create_combo_box( items=["None", "0", "1", "2", "3"], current_index="@binding(camera_index_model.value)") label_column = u.create_column( u.create_label(text=_("URL:")), u.create_label(text=_("Camera Index (0 for none):")), spacing=4) field_column = u.create_column(url_field, camera_index_combo, spacing=4) return u.create_row(label_column, field_column, u.create_stretch(), spacing=12)
def show_conflict_check_dialog(self, document_controller, metadata_elab, metadata_nion, dataitem, conflict_keys): ui_handler = ConflictCheckDialogUI().get_ui_handler( api_broker=PlugInManager.APIBroker(), event_loop=document_controller.event_loop, metadata_elab=metadata_elab, metadata_nion=metadata_nion, dataitem=dataitem, conflict_keys=conflict_keys, title='Resolve conflicts') finishes = list() dialog = Declarative.construct(document_controller.ui, document_controller, ui_handler.ui_view, ui_handler, finishes) for finish in finishes: finish() ui_handler._event_loop = document_controller.event_loop ui_handler.request_close = dialog.request_close ui_handler.parent_request_close = self.request_close dialog.show()
def __create_action_button(self, action: Window.Action) -> Declarative.UIDescription: action_id = action.action_id action_identifier = action_id.replace(".", "_") icon_png = getattr(action, "action_command_icon_png", None) if icon_png is not None: icon_data = CanvasItem.load_rgba_data_from_bytes(icon_png) else: icon_data = numpy.full((48, 64), 0x00FFFFFF, dtype=numpy.uint32) icon_data[8:40, 8:56] = 0xFFC0C0C0 icon_property = "icon_" + action_identifier setattr(self, icon_property, icon_data) tool_tip = getattr(action, "action_tool_tip", getattr(action, "action_name", None)) key_shortcut = Window.action_shortcuts.get(action_id, dict()).get("display_panel", None) if tool_tip and key_shortcut: tool_tip += f" ({key_shortcut})" u = Declarative.DeclarativeUI() perform_function = "perform_" + action_identifier def perform_action(widget: UserInterface.Widget) -> None: self.__document_controller.perform_action(action_id) setattr(self, perform_function, perform_action) return u.create_image(image=f"@binding({icon_property})", height=24, width=32, on_clicked=f"{perform_function}", tool_tip=tool_tip)
def construct(self, d_type: str, ui: UserInterface.UserInterface, window: typing.Optional[Window.Window], d: Declarative.UIDescription, handler: Declarative.HandlerLike, finishes: typing.List[typing.Callable[[], None]]) -> typing.Optional[UserInterface.Widget]: if d_type == "notification_char_button": font = "normal 13px serif" text = d["text"] fm = ui.get_font_metrics(font, text) canvas_item = CharButtonCanvasItem(text) widget = ui.create_canvas_widget(properties={"height": fm.height + 4, "width": fm.width + 4}) widget.canvas_item.add_canvas_item(canvas_item) if handler: Declarative.connect_name(widget, d, handler) Declarative.connect_attributes(widget, d, handler, finishes) Declarative.connect_event(widget, canvas_item, d, handler, "on_clicked", []) return widget return None
def show_file_param_dialog(self, file_ext: str = None, params_callback: callable = None): if self.__file_param_dialog_closed_event.is_set(): document_controller = self.__api.application.document_controllers[ 0]._document_controller ui_handler = OpenFileDialogUI().get_ui_handler( api_broker=PlugInManager.APIBroker(), event_loop=document_controller.event_loop, file_ext=file_ext, title='File') def dialog_closed(): self.__file_param_dialog_closed_event.set() ui_handler.on_closed = dialog_closed ui_handler.params_callback = params_callback finishes = list() dialog = Declarative.construct(document_controller.ui, document_controller, ui_handler.ui_view, ui_handler, finishes) for finish in finishes: finish() ui_handler._event_loop = document_controller.event_loop if callable(getattr(ui_handler, 'init_handler', None)): ui_handler.init_handler() dialog.show() ui_handler.request_close = dialog.request_close self.__file_param_dialog_closed_event.clear() self.__show_file_param_dialog_finished_event.set()
def __init__(self, app: Application.BaseApplication) -> None: super().__init__() notifications = ListModel.ListModel[Notification.Notification]() stack_index = Model.PropertyModel[int](0) self.notifications = notifications self.stack_index = stack_index def notification_changed(key: str, value: Notification.Notification, index: int) -> None: stack_index.value = 1 if len(notifications.items) > 0 else 0 self.__notification_inserted_listener = self.notifications.item_inserted_event.listen(notification_changed) self.__notification_removed_listener = self.notifications.item_removed_event.listen(notification_changed) u = Declarative.DeclarativeUI() main_column = u.create_column( u.create_stack( u.create_column( u.create_label(text=_("No notifications.")), u.create_stretch(), ), u.create_column( u.create_column(items="notifications.items", item_component_id="notification", spacing=6), u.create_stretch(), ), current_index="@binding(stack_index.value)" ), u.create_stretch(), spacing=8, width=460, min_height=260, ) window = u.create_window(main_column, title=_("Notifications"), margin=8, window_style="tool") self.run(window, app=app, persistent_id="notification_dialog")
def build(self, ui, event_loop=None, **kwargs): u = Declarative.DeclarativeUI() video_device_factories = list(Registry.get_components_by_type("video_device_factory")) class Handler: def __init__(self, ui_view, video_sources): self.ui_view = ui_view self.video_sources = video_sources self.video_source_type_index = Model.PropertyModel(0) def create_new_video_device(self, widget): video_base.video_configuration.create_hardware_source(video_device_factories[self.video_source_type_index.value]) def create_handler(self, component_id: str, container=None, item=None, **kwargs): class SectionHandler: def __init__(self, container, hardware_source): self.container = container self.hardware_source = hardware_source self.settings = video_base.video_configuration.get_settings_model(hardware_source) self.settings_original = copy.deepcopy(self.settings) self.needs_saving_model = Model.PropertyModel(False) self.property_changed_event = Event.Event() self.apply_button = None self.revert_button = None def settings_changed(property_name): self.needs_saving_model.value = True self.__settings_changed_event_listener = self.settings.property_changed_event.listen(settings_changed) def needs_saving_model_changed(property_name): if self.apply_button: self.apply_button.enabled = self.needs_saving_model.value if self.revert_button: self.revert_button.enabled = self.needs_saving_model.value self.__needs_saving_changed_event_listener = self.needs_saving_model.property_changed_event.listen(needs_saving_model_changed) def close(self): self.__settings_changed_event_listener.close() self.__settings_changed_event_listener = None def init_handler(self): self.apply_button.enabled = self.needs_saving_model.value self.revert_button.enabled = self.needs_saving_model.value def create_handler(self, component_id: str, container=None, item=None, **kwargs): if component_id == "edit_group": if self.__video_device_factory: return self.__video_device_factory.create_editor_handler(self.settings) else: return self @property def resources(self): if self.__video_device_factory: content = self.__video_device_factory.get_editor_description() else: content = u.create_label(text=_("Not Available")) component = u.define_component(content=content, component_id="edit_group") return {"edit_group": component} @property def __video_device_factory(self): for video_device_factory in video_device_factories: if video_device_factory.factory_id == self.settings.driver: return video_device_factory return None @property def driver_display_name(self) -> str: video_device_factory = self.__video_device_factory return video_device_factory.display_name if video_device_factory else _("Unknown") def apply(self, widget): video_base.video_configuration.set_settings_model(self.hardware_source, self.settings) self.needs_saving_model.value = False def revert(self, widget): self.settings.copy_from(self.settings_original) self.needs_saving_model.value = False def remove(self, widget): video_base.video_configuration.remove_hardware_source(self.hardware_source) if component_id == "section": return SectionHandler(container, item) @property def resources(self): u = Declarative.DeclarativeUI() driver_display_name_label = u.create_label(text="@binding(driver_display_name)") device_id_field = u.create_line_edit(text="@binding(settings.device_id)", width=180) display_name_field = u.create_line_edit(text="@binding(settings.name)", width=240) edit_group_content = u.create_component_instance("edit_group") edit_group = u.create_group(edit_group_content, margin=8) edit_row = u.create_row(edit_group, u.create_stretch()) apply_button = u.create_push_button(name="apply_button", text=_("Apply"), on_clicked="apply") revert_button = u.create_push_button(name="revert_button", text=_("Revert"), on_clicked="revert") remove_button = u.create_push_button(text=_("Remove"), on_clicked="remove") remove_row = u.create_row(apply_button, revert_button, remove_button, u.create_stretch()) label_column = u.create_column(u.create_label(text=_("Driver:")), u.create_label(text=_("Device ID:")), u.create_label(text=_("Display Name:")), spacing=4) field_column = u.create_column(driver_display_name_label, device_id_field, display_name_field, spacing=4) content_row = u.create_row(label_column, field_column, u.create_stretch(), spacing=12) content = u.create_column(content_row, edit_row, remove_row, spacing=8) component = u.define_component(content=content, component_id="section") return {"section": component} sources_column = u.create_column(items="video_sources.items", item_component_id="section", spacing=8) sources_content = u.create_scroll_area(u.create_column(sources_column, u.create_stretch())) video_source_types = [video_device_factory.display_name for video_device_factory in video_device_factories] video_source_type_combo = u.create_combo_box(items=video_source_types, current_index="@binding(video_source_type_index.value)") button_row = u.create_row(u.create_stretch(), video_source_type_combo, u.create_push_button(text=_("New"), on_clicked="create_new_video_device"), spacing=8) content = u.create_column(sources_content, button_row) return Declarative.DeclarativeWidget(ui, event_loop, Handler(content, self.__video_configuration.video_sources))