def __init__( self, *, image_acquisition: ImageAcquisitionService, features_params_factory: PendantFeaturesParamsFactory, features_service: PendantFeaturesService, ) -> None: self._image_acquisition = image_acquisition self.bn_active_tool = VariableBindable(ToolID.DROP_REGION) region_clip = AccessorBindable(getter=self._get_region_clip) self.drop_region_plugin = DefineRegionPluginModel( in_region=GObjectPropertyBindable(features_params_factory, 'drop-region'), in_clip=region_clip, ) self.needle_region_plugin = DefineRegionPluginModel( in_region=GObjectPropertyBindable(features_params_factory, 'needle-region'), in_clip=region_clip, ) self.preview_plugin = IFTPreviewPluginModel( image_acquisition=image_acquisition, features_params_factory=features_params_factory, features_service=features_service, )
def _do_init( self, view_context: ImageProcessorPluginViewContext, tool_id: Any, color: Tuple[float, float, float], label: str, z_index: int, ) -> None: self._view_context = view_context self._tool_ref = view_context.get_tool_item(tool_id) view_context.render.connect( 'cursor-up-event', lambda render, pos: self.presenter.cursor_up(pos), ) view_context.render.connect( 'cursor-down-event', lambda render, pos: self.presenter.cursor_down(pos), ) view_context.render.connect( 'cursor-motion-event', lambda render, pos: self.presenter.cursor_move(pos), ) self.bn_tool_button_is_active = self._tool_ref.bn_is_active self._render = view_context.render self._defined_ro = RectangleWithLabel( border_color=color, border_width=2, label=label, z_index=z_index, ) self._render.add_render_object(self._defined_ro) self._dragging_ro = Rectangle( border_color=color, border_width=1, z_index=z_index, ) self._render.add_render_object(self._dragging_ro) self.bn_dragging = GObjectPropertyBindable( g_obj=self._dragging_ro, prop_name='extents', ) self.bn_defined = GObjectPropertyBindable( g_obj=self._defined_ro, prop_name='extents', ) self.presenter.view_ready()
def _do_init( self, view_context: ImageProcessorPluginViewContext, tool_id: Any, color: Tuple[float, float, float], label: str, z_index: int, ) -> None: self._view_context = view_context self._tool_ref = view_context.get_tool_item(tool_id) view_context.canvas.connect( 'cursor-up', lambda canvas, pos: self.presenter.cursor_up(pos), ) view_context.canvas.connect( 'cursor-down', lambda canvas, pos: self.presenter.cursor_down(pos), ) view_context.canvas.connect( 'cursor-motion', lambda canvas, pos: self.presenter.cursor_move(pos), ) self.bn_tool_button_is_active = self._tool_ref.bn_is_active self._canvas = view_context.canvas self._defined_rect = RectangleArtist( stroke_color=color, stroke_width=1, scale_strokes=True, ) self._canvas.add_artist(self._defined_rect, z_index=z_index) self._dragging_rect = RectangleArtist( stroke_color=color, stroke_width=1, scale_strokes=True, ) self._canvas.add_artist(self._dragging_rect, z_index=z_index) self.bn_defined = GObjectPropertyBindable( g_obj=self._defined_rect, prop_name='extents', ) self.bn_dragging = GObjectPropertyBindable( g_obj=self._dragging_rect, prop_name='extents', ) self.presenter.view_ready()
def _do_init(self, view_context: ImageProcessorPluginViewContext) -> None: self._view_context = view_context self._tool_ref = self._view_context.get_tool_item( ToolID.EDGE_DETECTION) self.bn_tool_button_is_active = self._tool_ref.bn_is_active self._button_body = Gtk.Grid(hexpand=True, vexpand=True) self._tool_ref.button_interior.add(self._button_body) button_lbl = Gtk.Label( label="Edge detection", vexpand=True, valign=Gtk.Align.CENTER, ) self._button_body.add(button_lbl) self._button_body.show_all() self._popover = Gtk.Popover( relative_to=self._button_body, modal=False, ) # Prevent the popover from being dismissed by the user clicking on it. self._popover.connect('button-release-event', lambda *_: True) popover_body = Gtk.Grid( margin=10, width_request=250, ) self._popover.add(popover_body) canny_adjuster = CannyParameters() popover_body.add(canny_adjuster) self.bn_canny_min = GObjectPropertyBindable( g_obj=canny_adjuster, prop_name='min-thresh', ) self.bn_canny_max = GObjectPropertyBindable( g_obj=canny_adjuster, prop_name='max-thresh', ) popover_body.show_all() self.presenter.view_ready()
def fixture(self): # Reset the property getter and setter mocks (since they are shared with all instances) MockGObjectWithProperty.prop_getter.reset_mock() MockGObjectWithProperty.prop_setter.reset_mock() self.g_obj = MockGObjectWithProperty() self.g_obj_prop_bindable = GObjectPropertyBindable(self.g_obj, 'prop')
def set_referents( self, tool_id: Any, tool_button: Gtk.Button, tool_button_interior: Gtk.Grid, do_request_deactivate: Callable[[Any], Any], ) -> None: assert not self._referents_set self._referents_set = True self._bn_is_active = GObjectPropertyBindable( g_obj=tool_button, prop_name='active', ) self._tool_id = tool_id self._tool_button = tool_button self._tool_button_interior = tool_button_interior self._do_request_deactivate = do_request_deactivate
def _do_init(self) -> Gtk.Widget: self._render = Render(hexpand=True, vexpand=True) self._background_ro = PixbufFill() self._render.add_render_object(self._background_ro) surface_line_ro = Line(stroke_color=(0.25, 1.0, 0.25)) self._render.add_render_object(surface_line_ro) self.bn_surface_line = GObjectPropertyBindable(surface_line_ro, 'line') drop_contour_ro = Polyline(stroke_color=(0.0, 0.5, 1.0)) self._render.add_render_object(drop_contour_ro) self.bn_drop_contours = GObjectPropertyBindable( drop_contour_ro, 'polyline') left_angle_ro = Angle(stroke_color=(1.0, 0.0, 0.5), clockwise=False) self._render.add_render_object(left_angle_ro) self.bn_left_angle = GObjectPropertyBindable(left_angle_ro, 'delta-angle') self.bn_left_point = GObjectPropertyBindable(left_angle_ro, 'vertex-pos') surface_line_ro.bind_property( 'line', left_angle_ro, 'start-angle', GObject.BindingFlags.SYNC_CREATE, lambda _, line: -math.atan(line.gradient) if line is not None else 0) right_angle_ro = Angle(stroke_color=(1.0, 0.0, 0.5), clockwise=True) self._render.add_render_object(right_angle_ro) self.bn_right_angle = GObjectPropertyBindable( right_angle_ro, 'delta-angle', transform_to=lambda angle: -angle, transform_from=lambda angle: -angle) self.bn_right_point = GObjectPropertyBindable(right_angle_ro, 'vertex-pos') surface_line_ro.bind_property( 'line', right_angle_ro, 'start-angle', GObject.BindingFlags.SYNC_CREATE, lambda _, line: math.pi - (math.atan(line.gradient) if line is not None else 0)) self.presenter.view_ready() return self._render
def _do_init(self, footer_area: Gtk.Grid) -> Gtk.Widget: self._widget = Gtk.Grid(margin=10, column_spacing=10, row_spacing=10) image_source_lbl = Gtk.Label('Image source:') self._widget.attach(image_source_lbl, 0, 0, 1, 1) self._image_source_combobox = Gtk.ComboBoxText(hexpand=True, halign=Gtk.Align.START) self._widget.attach(self._image_source_combobox, 1, 0, 1, 1) self._populate_combobox() self._widget.attach( Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL, hexpand=True), 0, 1, 2, 1) _, configurator_area = self.new_component( configurator_cs.factory(in_acquirer=self.presenter.bn_acquirer)) self._widget.attach(configurator_area, 0, 2, 2, 1) self.bn_selected_acquirer_type = GObjectPropertyBindable( g_obj=self._image_source_combobox, prop_name='active-id', transform_to=lambda e: e.name if e is not None else None, transform_from=lambda name: AcquirerType[name] if name is not None else None, ) # type: Bindable[Optional[str]] _, footer_inside = self.new_component( linear_navigator_footer_cs.factory( do_next=self.presenter.next_page)) footer_inside.show() footer_area.add(footer_inside) self.presenter.view_ready() self._widget.foreach(Gtk.Widget.show) return self._widget
def _do_init(self) -> Gtk.Grid: self._widget = Gtk.Grid(column_spacing=5) left_btn = Gtk.Button('<') self._widget.attach(left_btn, 0, 0, 1, 1) self._idx_inp = IntegerEntry(lower=1, width_chars=3) self._widget.attach(self._idx_inp, 1, 0, 1, 1) self._num_images_lbl = Gtk.Label() self._widget.attach(self._num_images_lbl, 2, 0, 1, 1) right_btn = Gtk.Button('>') self._widget.attach(right_btn, 3, 0, 1, 1) self.bn_show_index = GObjectPropertyBindable( g_obj=self._idx_inp, prop_name='value', # User input is 1-based indexing transform_to=lambda x: x + 1 if x is not None else None, transform_from=lambda x: x - 1 if x is not None else None, ) self._idx_inp.connect( 'activate', lambda *_: self.presenter.view_show_idx_changed()) self._idx_inp.connect( 'focus-out-event', lambda *_: self.presenter.view_show_idx_changed()) left_btn.connect('clicked', lambda *_: self.presenter.prev_image()) right_btn.connect('clicked', lambda *_: self.presenter.next_image()) self._widget.show_all() self.presenter.view_ready() return self._widget
def _do_init(self, parent_window: Optional[Gtk.Window]) -> Gtk.Window: self._window = Gtk.Window( title='Select camera', transient_for=parent_window, resizable=False, modal=True, window_position=Gtk.WindowPosition.CENTER, ) body = Gtk.Grid() self._window.add(body) content = Gtk.Grid(margin=10, column_spacing=10) body.attach(content, 0, 0, 1, 1) camera_index_lbl = Gtk.Label('Camera index:') content.attach(camera_index_lbl, 0, 0, 1, 1) camera_index_inp = IntegerEntry(lower=0, upper=99999, max_length=5, width_chars=6) camera_index_inp.get_style_context().add_class('small-pad') content.attach_next_to(camera_index_inp, camera_index_lbl, Gtk.PositionType.RIGHT, 1, 1) # Setting max_width_chars to 0 seems to allow the label to occupy as much space as its parent, allowing # line wrapping to work. self._error_msg_lbl = Gtk.Label(margin_top=10, max_width_chars=0) self._error_msg_lbl.set_line_wrap(True) self._error_msg_lbl.get_style_context().add_class('error-text') content.attach(self._error_msg_lbl, 0, 1, 2, 1) footer = Gtk.Grid() footer.get_style_context().add_class('change-cam-dialog-view-footer') footer.get_style_context().add_class('linked') body.attach(footer, 0, 1, 1, 1) cancel_btn = Gtk.Button('Cancel', hexpand=True) cancel_btn.get_style_context().add_class('dialog-footer-button') footer.attach(cancel_btn, 0, 0, 1, 1) connect_btn = Gtk.Button('Connect', hexpand=True) connect_btn.get_style_context().add_class('dialog-footer-button') footer.attach(connect_btn, 1, 0, 1, 1) self._window.show_all() # Hide the error message label (since self.widget.show_all() would have made all descendant widgets # visible). self._error_msg_lbl.hide() # Wiring things up connect_btn.connect('clicked', lambda *_: self.presenter.connect()) cancel_btn.connect('clicked', lambda *_: self.presenter.cancel()) self._window.connect('delete-event', self._hdl_widget_delete_event) self.bn_camera_index = GObjectPropertyBindable(camera_index_inp, 'value') # type: Bindable[int] self.bn_connect_btn_sensitive = GObjectPropertyBindable(connect_btn, 'sensitive') # type: Bindable[bool] self.presenter.view_ready() return self._window
def _do_init( self, view_context: ImageProcessorPluginViewContext, tool_id: Any, color: Tuple[float, float, float], z_index: int, ) -> None: self._view_context = view_context self._tool_ref = view_context.get_tool_item(tool_id) view_context.canvas.connect( 'cursor-up', lambda canvas, pos: self.presenter.cursor_up(pos), ) view_context.canvas.connect( 'cursor-down', lambda canvas, pos: self.presenter.cursor_down(pos), ) view_context.canvas.connect( 'cursor-motion', lambda canvas, pos: self.presenter.cursor_move(pos), ) view_context.canvas.connect( 'key-press-event', self._hdl_canvas_key_press_event, ) self.bn_tool_button_is_active = self._tool_ref.bn_is_active self._canvas = view_context.canvas self._defined_artist = LineArtist( stroke_color=color, stroke_width=1, scale_strokes=True, ) self._canvas.add_artist(self._defined_artist, z_index=z_index) self._dragging_artist = LineArtist( stroke_color=color, stroke_width=1, scale_strokes=True, ) self._canvas.add_artist(self._dragging_artist, z_index=z_index) self._control_point_artist = CircleArtist( fill_color=color, scale_radius=True, ) self._canvas.add_artist(self._control_point_artist, z_index=z_index) self.bn_defined = GObjectPropertyBindable( g_obj=self._defined_artist, prop_name='line', ) self.bn_dragging = GObjectPropertyBindable( g_obj=self._dragging_artist, prop_name='line', ) self.presenter.view_ready()
def _do_init(self) -> Gtk.Widget: self._widget = Gtk.Grid(row_spacing=10, hexpand=False, width_request=220) parameters_lbl = Gtk.Label(xalign=0) parameters_lbl.set_markup('<b>Parameters</b>') self._widget.attach(parameters_lbl, 0, 0, 1, 1) sheet = Gtk.Grid(row_spacing=10, column_spacing=10) self._widget.attach(sheet, 0, 1, 1, 1) interfacial_tension_lbl = Gtk.Label('IFT (mN/m):', xalign=0) sheet.attach(interfacial_tension_lbl, 0, 0, 1, 1) volume_lbl = Gtk.Label('Volume (mm³):', xalign=0) sheet.attach(volume_lbl, 0, 1, 1, 1) surface_area_lbl = Gtk.Label('Surface area (mm²):', xalign=0) sheet.attach(surface_area_lbl, 0, 2, 1, 1) sheet.attach( Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL, hexpand=True), 0, 3, 2, 1) worthington_lbl = Gtk.Label('Worthington:', xalign=0) sheet.attach(worthington_lbl, 0, 4, 1, 1) bond_number_lbl = Gtk.Label('Bond number:', xalign=0) sheet.attach(bond_number_lbl, 0, 5, 1, 1) apex_coords_lbl = Gtk.Label('Apex coordinates (px):', xalign=0) sheet.attach(apex_coords_lbl, 0, 6, 1, 1) image_angle_lbl = Gtk.Label('Image angle:', xalign=0) sheet.attach(image_angle_lbl, 0, 7, 1, 1) interfacial_tension_val = Gtk.Label(xalign=0) sheet.attach_next_to(interfacial_tension_val, interfacial_tension_lbl, Gtk.PositionType.RIGHT, 1, 1) volume_val = Gtk.Label(xalign=0) sheet.attach_next_to(volume_val, volume_lbl, Gtk.PositionType.RIGHT, 1, 1) surface_area_val = Gtk.Label(xalign=0) sheet.attach_next_to(surface_area_val, surface_area_lbl, Gtk.PositionType.RIGHT, 1, 1) worthington_val = Gtk.Label(xalign=0) sheet.attach_next_to(worthington_val, worthington_lbl, Gtk.PositionType.RIGHT, 1, 1) bond_number_val = Gtk.Label(xalign=0) sheet.attach_next_to(bond_number_val, bond_number_lbl, Gtk.PositionType.RIGHT, 1, 1) apex_coords_val = Gtk.Label(xalign=0) sheet.attach_next_to(apex_coords_val, apex_coords_lbl, Gtk.PositionType.RIGHT, 1, 1) image_angle_val = Gtk.Label(xalign=0) sheet.attach_next_to(image_angle_val, image_angle_lbl, Gtk.PositionType.RIGHT, 1, 1) self._widget.foreach(Gtk.Widget.show_all) self.bn_interfacial_tension = GObjectPropertyBindable( interfacial_tension_val, 'label', transform_to=lambda v: '{:.4g}'.format(v * 1e3), ) # type: WriteBindable[float] self.bn_volume = GObjectPropertyBindable( volume_val, 'label', transform_to=lambda v: '{:.4g}'.format(v * 1e9), ) # type: WriteBindable[float] self.bn_surface_area = GObjectPropertyBindable( surface_area_val, 'label', transform_to=lambda v: '{:.4g}'.format(v * 1e6), ) # type: WriteBindable[float] self.bn_worthington = GObjectPropertyBindable( worthington_val, 'label', transform_to=lambda v: '{:.4g}'.format(v), ) # type: WriteBindable[float] self.bn_bond_number = GObjectPropertyBindable( bond_number_val, 'label', transform_to=lambda v: '{:.4g}'.format(v), ) # type: WriteBindable[float] self.bn_apex_coords = GObjectPropertyBindable( apex_coords_val, 'label', transform_to=lambda v: '({0[0]:.4g}, {0[1]:.4g})'.format( v)) # type: WriteBindable[Tuple[float, float]] self.bn_image_angle = GObjectPropertyBindable( image_angle_val, 'label', transform_to=lambda v: '{:.4g}°'.format(math.degrees( v))) # type: WriteBindable[float] self.presenter.view_ready() return self._widget
def _do_init(self) -> Gtk.Widget: self._widget = Gtk.Grid(row_spacing=10, column_spacing=10) file_chooser_lbl = Gtk.Label('Image files:', xalign=0) self._widget.attach(file_chooser_lbl, 0, 0, 1, 1) self._file_chooser_inp = FileChooserButton( file_filter=self._FILE_INPUT_FILTER, select_multiple=True) self._file_chooser_inp.get_style_context().add_class('small-pad') self._widget.attach_next_to(self._file_chooser_inp, file_chooser_lbl, Gtk.PositionType.RIGHT, 1, 1) frame_interval_lbl = Gtk.Label('Frame interval (s):') self._widget.attach(frame_interval_lbl, 0, 1, 1, 1) frame_interval_inp_container = Gtk.Grid() self._widget.attach_next_to(frame_interval_inp_container, frame_interval_lbl, Gtk.PositionType.RIGHT, 1, 1) self._frame_interval_inp = FloatEntry(lower=0, width_chars=6, invisible_char='\0', caps_lock_warning=False) self._frame_interval_inp.get_style_context().add_class('small-pad') frame_interval_inp_container.add(self._frame_interval_inp) # Error message labels self._file_chooser_err_msg_lbl = Gtk.Label(xalign=0) self._file_chooser_err_msg_lbl.get_style_context().add_class( 'error-text') self._widget.attach_next_to(self._file_chooser_err_msg_lbl, self._file_chooser_inp, Gtk.PositionType.RIGHT, 1, 1) self._frame_interval_err_msg_lbl = Gtk.Label(xalign=0) self._frame_interval_err_msg_lbl.get_style_context().add_class( 'error-text') self._widget.attach_next_to(self._frame_interval_err_msg_lbl, frame_interval_inp_container, Gtk.PositionType.RIGHT, 1, 1) self._widget.show_all() self._frame_interval_inp.bind_property( 'sensitive', self._frame_interval_inp, 'visibility', GObject.BindingFlags.SYNC_CREATE) self.bn_selected_image_paths = GObjectPropertyBindable( self._file_chooser_inp, 'file-paths') self.bn_frame_interval = GObjectPropertyBindable( self._frame_interval_inp, 'value') self.bn_frame_interval_sensitive = GObjectPropertyBindable( self._frame_interval_inp, 'sensitive') # Set which widget is first focused self._file_chooser_inp.grab_focus() self.presenter.view_ready() return self._widget
def _do_init( self, view_context: ImageProcessorPluginViewContext, tool_id: Any, color: Tuple[float, float, float], z_index: int, ) -> None: self._view_context = view_context self._tool_ref = view_context.get_tool_item(tool_id) view_context.render.connect( 'cursor-up-event', lambda render, pos: self.presenter.cursor_up(pos), ) view_context.render.connect( 'cursor-down-event', lambda render, pos: self.presenter.cursor_down(pos), ) view_context.render.connect( 'cursor-motion-event', lambda render, pos: self.presenter.cursor_move(pos), ) view_context.render.connect( 'key-press-event', self._hdl_render_key_press_event ) self.bn_tool_button_is_active = self._tool_ref.bn_is_active self._render = view_context.render self._defined_ro = Line( stroke_color=color, stroke_width=2, draw_control_points=False, z_index=z_index, ) self._render.add_render_object(self._defined_ro) self._dragging_ro = Line( stroke_color=color, stroke_width=1, draw_control_points=True, z_index=z_index, ) self._render.add_render_object(self._dragging_ro) self.bn_dragging = GObjectPropertyBindable( g_obj=self._dragging_ro, prop_name='line', ) self.bn_defined = GObjectPropertyBindable( g_obj=self._defined_ro, prop_name='line', ) self.presenter.view_ready()
def _do_init(self, view_context: ImageProcessorPluginViewContext) -> None: self._view_context = view_context self._tool_ref = self._view_context.get_tool_item( ToolID.FOREGROUND_DETECTION) self.bn_tool_button_is_active = self._tool_ref.bn_is_active self._button_body = Gtk.Grid(hexpand=True, vexpand=True) self._tool_ref.button_interior.add(self._button_body) button_lbl = Gtk.Label( label="Foreground detection", vexpand=True, valign=Gtk.Align.CENTER, ) self._button_body.add(button_lbl) self._button_body.show_all() self._popover = Gtk.Popover( relative_to=self._button_body, modal=False, ) # Prevent the popover from being dismissed by the user clicking on it. self._popover.connect('button-release-event', lambda *_: True) popover_body = Gtk.Grid( margin=10, row_spacing=10, column_spacing=10, width_request=250, ) self._popover.add(popover_body) thresh_inp = Gtk.Adjustment(value=255, lower=1, upper=255) thresh_lbl = Gtk.Label('Threshold:', halign=Gtk.Align.START) popover_body.attach(thresh_lbl, 0, 0, 1, 1) thresh_scl = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, adjustment=thresh_inp, hexpand=True, draw_value=False) thresh_scl.get_style_context().add_class('small-pad') thresh_scl.get_style_context().add_provider( self._STYLE_PROV, Gtk.STYLE_PROVIDER_PRIORITY_USER) thresh_scl.show() popover_body.attach(thresh_scl, 1, 0, 1, 1) thresh_ety = FloatEntry(width_chars=5, xalign=0) thresh_ety.get_style_context().add_class('small-pad') thresh_ety.get_style_context().add_provider( self._STYLE_PROV, Gtk.STYLE_PROVIDER_PRIORITY_USER) thresh_ety.show() popover_body.attach(thresh_ety, 2, 0, 1, 1) # Bind the properties of Gtk.Adjustment to the Gtk.Entry widget. for (src, targ), prop in itertools.product( ((thresh_inp, thresh_ety), ), ('value', 'lower', 'upper')): src.bind_property( prop, # source_property targ, prop, # target, target_property GObject.BindingFlags.BIDIRECTIONAL # flags | GObject.BindingFlags.SYNC_CREATE, lambda _, v: round(v, 1), # transform_to lambda _, v: v # transform_from ) self.bn_thresh = GObjectPropertyBindable( g_obj=thresh_inp, prop_name='value', ) popover_body.show_all() self.presenter.view_ready()
def _do_init(self, parent_window: Optional[Gtk.Window] = None) -> Gtk.Window: self._window = Gtk.Window( title='Save analysis', resizable=False, modal=True, transient_for=parent_window, window_position=Gtk.WindowPosition.CENTER, ) body = Gtk.Grid(margin=10, row_spacing=10) self._window.add(body) content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) body.attach(content, 0, 0, 1, 1) save_location_frame = Gtk.Frame(label='Save location') content.add(save_location_frame) save_location_content = Gtk.Grid(margin=10, column_spacing=10, row_spacing=5) save_location_frame.add(save_location_content) save_dir_lbl = Gtk.Label('Parent:', xalign=0) save_location_content.attach(save_dir_lbl, 0, 0, 1, 1) self._save_dir_parent_inp = Gtk.FileChooserButton(action=Gtk.FileChooserAction.SELECT_FOLDER, hexpand=True) self._save_dir_parent_inp.get_style_context().add_class('small-combobox') save_location_content.attach_next_to(self._save_dir_parent_inp, save_dir_lbl, Gtk.PositionType.RIGHT, 1, 1) save_dir_parent_err_lbl = Gtk.Label(xalign=0, width_request=190) save_dir_parent_err_lbl.get_style_context().add_class('error-text') save_location_content.attach_next_to(save_dir_parent_err_lbl, self._save_dir_parent_inp, Gtk.PositionType.RIGHT, 1, 1) save_name_lbl = Gtk.Label('Name:', xalign=0) save_location_content.attach(save_name_lbl, 0, 1, 1, 1) save_dir_name_inp = Gtk.Entry() save_dir_name_inp.get_style_context().add_class('small-pad') save_location_content.attach_next_to(save_dir_name_inp, save_name_lbl, Gtk.PositionType.RIGHT, 1, 1) save_dir_name_err_lbl = Gtk.Label(xalign=0, width_request=190) save_dir_name_err_lbl.get_style_context().add_class('error-text') save_location_content.attach_next_to(save_dir_name_err_lbl, save_dir_name_inp, Gtk.PositionType.RIGHT, 1, 1) figures_frame = Gtk.Frame(label='Figures') content.add(figures_frame) figures_content = Gtk.Grid(margin=10, column_spacing=10, row_spacing=5) figures_frame.add(figures_content) _, angles_figure_options_area = self.new_component( figure_options_cs.factory( model=self.presenter.angle_figure_options, figure_name='contact angles plot', ) ) angles_figure_options_area.show() figures_content.attach(angles_figure_options_area, 0, 0, 1, 1) footer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) body.attach_next_to(footer, content, Gtk.PositionType.BOTTOM, 1, 1) ok_btn = Gtk.Button('OK') ok_btn.get_style_context().add_class('conan-analysis-saver-view-footer-button') footer.pack_end(ok_btn, expand=False, fill=False, padding=0) cancel_btn = Gtk.Button('Cancel') cancel_btn.get_style_context().add_class('conan-analysis-saver-view-footer-button') footer.pack_end(cancel_btn, expand=False, fill=False, padding=0) self._window.show_all() # Wiring things up ok_btn.connect('clicked', lambda *_: self.presenter.ok()) cancel_btn.connect('clicked', lambda *_: self.presenter.cancel()) self._window.connect('delete-event', self._hdl_window_delete_event) self.bn_save_dir_parent = AccessorBindable(self._get_save_dir_parent, self._set_save_dir_parent) self.bn_save_dir_name = GObjectPropertyBindable(save_dir_name_inp, 'text') self._confirm_overwrite_dialog = None self._file_exists_info_dialog = None self.presenter.view_ready() return self._window
def _do_init(self, footer_area: Gtk.Grid) -> Gtk.Widget: self._widget = Gtk.Grid(margin=20, row_spacing=10, column_spacing=10) # Label widgets inner_density_lbl = Gtk.Label('Inner density (kg/m³):', xalign=0) self._widget.attach(inner_density_lbl, 0, 0, 1, 1) outer_density_lbl = Gtk.Label('Outer density (kg/m³):', xalign=0) self._widget.attach(outer_density_lbl, 0, 1, 1, 1) needle_width_lbl = Gtk.Label('Needle diameter (mm):', xalign=0) self._widget.attach(needle_width_lbl, 0, 2, 1, 1) gravity_lbl = Gtk.Label('Gravity (m/s²):', xalign=0) self._widget.attach(gravity_lbl, 0, 3, 1, 1) # Input widgets self._inner_density_inp = FloatEntry(lower=0, width_chars=10) self._widget.attach_next_to(self._inner_density_inp, inner_density_lbl, Gtk.PositionType.RIGHT, 1, 1) self._outer_density_inp = FloatEntry(lower=0, width_chars=10) self._widget.attach_next_to(self._outer_density_inp, outer_density_lbl, Gtk.PositionType.RIGHT, 1, 1) self._needle_width_inp = FloatEntry(lower=0, width_chars=10) self._widget.attach_next_to(self._needle_width_inp, needle_width_lbl, Gtk.PositionType.RIGHT, 1, 1) self._gravity_inp = FloatEntry(lower=0, width_chars=10) self._widget.attach_next_to(self._gravity_inp, gravity_lbl, Gtk.PositionType.RIGHT, 1, 1) self._inner_density_err_msg_lbl = Gtk.Label(xalign=0) self._inner_density_err_msg_lbl.get_style_context().add_class( 'error-text') self._widget.attach_next_to(self._inner_density_err_msg_lbl, self._inner_density_inp, Gtk.PositionType.RIGHT, 1, 1) self._outer_density_err_msg_lbl = Gtk.Label(xalign=0) self._outer_density_err_msg_lbl.get_style_context().add_class( 'error-text') self._widget.attach_next_to(self._outer_density_err_msg_lbl, self._outer_density_inp, Gtk.PositionType.RIGHT, 1, 1) self._needle_width_err_msg_lbl = Gtk.Label(xalign=0) self._needle_width_err_msg_lbl.get_style_context().add_class( 'error-text') self._widget.attach_next_to(self._needle_width_err_msg_lbl, self._needle_width_inp, Gtk.PositionType.RIGHT, 1, 1) self._gravity_err_msg_lbl = Gtk.Label(xalign=0) self._gravity_err_msg_lbl.get_style_context().add_class('error-text') self._widget.attach_next_to(self._gravity_err_msg_lbl, self._gravity_inp, Gtk.PositionType.RIGHT, 1, 1) self._widget.show_all() self.bn_inner_density = GObjectPropertyBindable( g_obj=self._inner_density_inp, prop_name='value', ) self.bn_outer_density = GObjectPropertyBindable( g_obj=self._outer_density_inp, prop_name='value', ) self.bn_needle_width = GObjectPropertyBindable( g_obj=self._needle_width_inp, prop_name='value', # Needle width shown to user is in millimetres. transform_from=lambda x: x / 1000 if x is not None else None, transform_to=lambda x: x * 1000 if x is not None else None, ) self.bn_gravity = GObjectPropertyBindable( g_obj=self._gravity_inp, prop_name='value', ) _, footer_inside = self.new_component( linear_navigator_footer_cs.factory( do_back=self.presenter.prev_page, do_next=self.presenter.next_page, )) footer_inside.show() footer_area.add(footer_inside) self.presenter.view_ready() return self._widget
def _do_init(self, figure_name: str) -> Gtk.Widget: self._widget = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) self._should_save_figure_inp = Gtk.CheckButton( label='Save {}'.format(figure_name)) self._widget.add(self._should_save_figure_inp) self._more_options = Gtk.Grid(margin_left=30, row_spacing=5, column_spacing=10) self._widget.add(self._more_options) dpi_lbl = Gtk.Label('Figure DPI:', xalign=0) self._more_options.attach(dpi_lbl, 0, 0, 1, 1) dpi_inp_ctn = Gtk.Grid() self._more_options.attach_next_to(dpi_inp_ctn, dpi_lbl, Gtk.PositionType.RIGHT, 1, 1) dpi_inp = IntegerEntry(value=300, lower=72, upper=10000, width_chars=5) dpi_inp.get_style_context().add_class('small-pad') dpi_inp_ctn.add(dpi_inp) dpi_err_lbl = Gtk.Label(xalign=0, width_request=190) dpi_err_lbl.get_style_context().add_class('error-text') self._more_options.attach_next_to(dpi_err_lbl, dpi_inp_ctn, Gtk.PositionType.RIGHT, 1, 1) size_lbl = Gtk.Label('Figure size (cm):', xalign=0) self._more_options.attach(size_lbl, 0, 1, 1, 1) size_inp_ctn = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) self._more_options.attach_next_to(size_inp_ctn, size_lbl, Gtk.PositionType.RIGHT, 1, 1) size_w_lbl = Gtk.Label('W:') size_inp_ctn.add(size_w_lbl) size_w_inp = FloatEntry(value=10, lower=0, upper=10000, width_chars=6) size_w_inp.get_style_context().add_class('small-pad') size_inp_ctn.add(size_w_inp) size_h_lbl = Gtk.Label('H:') size_inp_ctn.add(size_h_lbl) size_h_inp = FloatEntry(value=10, lower=0, upper=10000, width_chars=6) size_h_inp.get_style_context().add_class('small-pad') size_inp_ctn.add(size_h_inp) size_err_lbl = Gtk.Label(xalign=0, width_request=190) size_err_lbl.get_style_context().add_class('error-text') self._more_options.attach_next_to(size_err_lbl, size_inp_ctn, Gtk.PositionType.RIGHT, 1, 1) self._should_save_figure_inp.bind_property( 'active', # source_property self._more_options, # target 'sensitive', # target_property GObject.BindingFlags.SYNC_CREATE, # flags ) self.bn_should_save = GObjectPropertyBindable( g_obj=self._should_save_figure_inp, prop_name='active', ) self.bn_dpi = GObjectPropertyBindable( g_obj=dpi_inp, prop_name='value', ) self.bn_size_w = GObjectPropertyBindable( g_obj=size_w_inp, prop_name='value', ) self.bn_size_h = GObjectPropertyBindable( g_obj=size_h_inp, prop_name='value', ) self.presenter.view_ready() self._widget.show_all() return self._widget
def _do_init(self) -> Gtk.Widget: self._change_camera_dialog_cid = None # type: Any self._widget = Gtk.Grid(row_spacing=10, column_spacing=10) # Populate self.widget camera_container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) self._widget.attach(camera_container, 0, 0, 2, 1) camera_lbl = Gtk.Label('Camera:', xalign=0) camera_container.add(camera_lbl) self._current_camera_lbl = Gtk.Label(xalign=0) camera_container.add(self._current_camera_lbl) self._change_camera_btn = Gtk.Button('Connect camera') self._change_camera_btn.get_style_context().add_class('small-pad') camera_container.add(self._change_camera_btn) num_frames_lbl = Gtk.Label('Number of images to capture:', xalign=0) self._widget.attach(num_frames_lbl, 0, 1, 1, 1) num_frames_inp_container = Gtk.Grid() self._widget.attach_next_to(num_frames_inp_container, num_frames_lbl, Gtk.PositionType.RIGHT, 1, 1) self._num_frames_inp = IntegerEntry(lower=1, upper=200, value=1, width_chars=6) self._num_frames_inp.get_style_context().add_class('small-pad') num_frames_inp_container.add(self._num_frames_inp) frame_interval_lbl = Gtk.Label('Frame interval (s):', xalign=0) self._widget.attach(frame_interval_lbl, 0, 2, 1, 1) frame_interval_inp_container = Gtk.Grid() self._widget.attach_next_to(frame_interval_inp_container, frame_interval_lbl, Gtk.PositionType.RIGHT, 1, 1) self._frame_interval_inp = FloatEntry(lower=0, width_chars=6, sensitive=False, invisible_char='\0') self._frame_interval_inp.get_style_context().add_class('small-pad') frame_interval_inp_container.add(self._frame_interval_inp) self._current_camera_err_msg_lbl = Gtk.Label(xalign=0) self._current_camera_err_msg_lbl.get_style_context().add_class('error-text') self._widget.attach_next_to(self._current_camera_err_msg_lbl, camera_container, Gtk.PositionType.RIGHT, 1, 1) self._num_frames_err_msg_lbl = Gtk.Label(xalign=0) self._num_frames_err_msg_lbl.get_style_context().add_class('error-text') self._widget.attach_next_to(self._num_frames_err_msg_lbl, num_frames_inp_container, Gtk.PositionType.RIGHT, 1, 1) self._frame_interval_err_msg_lbl = Gtk.Label(xalign=0) self._frame_interval_err_msg_lbl.get_style_context().add_class('error-text') self._widget.attach_next_to(self._frame_interval_err_msg_lbl, frame_interval_inp_container, Gtk.PositionType.RIGHT, 1, 1) self._widget.show_all() # Wiring things up self._change_camera_btn.connect('clicked', lambda *_: self.presenter.hdl_change_camera_btn_clicked()) self.bn_frame_interval = GObjectPropertyBindable(self._frame_interval_inp, 'value') self.bn_num_frames = GObjectPropertyBindable(self._num_frames_inp, 'value') self.bn_frame_interval_sensitive = GObjectPropertyBindable(self._frame_interval_inp, 'sensitive') self._frame_interval_inp.bind_property( 'sensitive', self._frame_interval_inp, 'visibility', GObject.BindingFlags.SYNC_CREATE ) self.presenter.view_ready() return self._widget