class UCSettingsPanel(wx.Panel): def __init__(self, *args, **kwds): super(UCSettingsPanel, self).__init__(*args, **kwds) self.phil_params = args[0].phil_params # Needed to draw and delete the rings. XXX Applies to # calibration_frame as well? self._pyslip = self.GetParent().GetParent().pyslip sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) # Number of decimal digits for distances. self.digits = 2 # Wavelength control. beam = self._pyslip.tiles.raw_image.get_beam() self._wavelength = beam.get_wavelength() # Unit cell controls. if self.phil_params.calibrate_unit_cell.unit_cell is not None: self._cell = list( self.phil_params.calibrate_unit_cell.unit_cell.parameters()) else: self._cell = [4.18, 4.72, 58.38, 89.44, 89.63, 75.85] if self.phil_params.calibrate_unit_cell.space_group is not None: self._spacegroup = self.phil_params.calibrate_unit_cell.space_group else: self._spacegroup = "P1" self._show_hkl = self.phil_params.calibrate_unit_cell.show_hkl self._cell_control_names = [ "uc_a_ctrl", "uc_b_ctrl", "uc_c_ctrl", "uc_alpha_ctrl", "uc_beta_ctrl", "uc_gamma_ctrl", ] box = wx.BoxSizer(wx.HORIZONTAL) self.uc_a = FloatSpin( self, digits=self.digits, name=self._cell_control_names[0], value=self._cell[0], ) box.Add(self.uc_a, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="a"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_a) self.uc_alpha = FloatSpin( self, digits=self.digits, name=self._cell_control_names[3], value=self._cell[3], ) box.Add( self.uc_alpha, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add(wx.StaticText(self, label="alpha"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_alpha) sizer.Add(box) box = wx.BoxSizer(wx.HORIZONTAL) self.uc_b = FloatSpin( self, digits=self.digits, name=self._cell_control_names[1], value=self._cell[1], ) box.Add(self.uc_b, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="b"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_b) self.uc_beta = FloatSpin( self, digits=self.digits, name=self._cell_control_names[4], value=self._cell[4], ) box.Add(self.uc_beta, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="beta"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_beta) sizer.Add(box) box = wx.BoxSizer(wx.HORIZONTAL) self.uc_c = FloatSpin( self, digits=self.digits, name=self._cell_control_names[2], value=self._cell[2], ) box.Add(self.uc_c, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="c"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_c) self.uc_gamma = FloatSpin( self, digits=self.digits, name=self._cell_control_names[5], value=self._cell[5], ) box.Add( self.uc_gamma, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add(wx.StaticText(self, label="gamma"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_gamma) sizer.Add(box) # Space group control box = wx.BoxSizer(wx.HORIZONTAL) self.space_group_ctrl = wx.TextCtrl(self, name="space group", value=self._spacegroup) box.Add( self.space_group_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Space group"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(wx.EVT_TEXT, self.OnSpaceGroup, self.space_group_ctrl) sizer.Add(box) # Distance control img = self.GetParent().GetParent()._img box = wx.BoxSizer(wx.HORIZONTAL) self.distance_ctrl = FloatSpin( self, digits=self.digits, name="Detector Distance", value=img.get_detector_distance(), ) self.distance_ctrl.SetIncrement(0.5) box.Add( self.distance_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) txtd = wx.StaticText(self, label="Detector Distance") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.distance_ctrl) sizer.Add(box) # Wavelength control img = self.GetParent().GetParent()._img box = wx.BoxSizer(wx.HORIZONTAL) self.wavelength_ctrl = FloatSpin(self, digits=4, name="Wavelength", value=img.get_wavelength()) self.wavelength_ctrl.SetIncrement(0.05) box.Add( self.wavelength_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) txtw = wx.StaticText(self, label="Wavelength") box.Add(txtw, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.wavelength_ctrl) sizer.Add(box) # d_min control if self.phil_params.calibrate_unit_cell.d_min is not None: self.d_min = self.phil_params.calibrate_unit_cell.d_min else: self.d_min = 3.5 box = wx.BoxSizer(wx.HORIZONTAL) self.d_min_ctrl = FloatSpin(self, digits=self.digits, name="d_min", value=self.d_min) box.Add( self.d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) txtd = wx.StaticText(self, label="Highest resolution for ring display") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.d_min_ctrl) sizer.Add(box) # Centering controls. self._center = [0, 0] box = wx.BoxSizer(wx.HORIZONTAL) self.spinner_fast = FloatSpin(self, digits=self.digits, name="fast_ctrl", value=self._center[0]) box.Add( self.spinner_fast, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center fast"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_fast) self.spinner_slow = FloatSpin(self, digits=self.digits, name="slow_ctrl", value=self._center[1]) box.Add( self.spinner_slow, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center slow"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) origin_box = wx.BoxSizer(wx.HORIZONTAL) self.origin = wx.StaticText(self, label="") origin_box.Add(self.origin, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_slow) sizer.Add(box) sizer.Add(origin_box) self.DrawRings() def __del__(self): if hasattr(self, "_ring_layer") and self._ring_layer is not None: self._pyslip.DeleteLayer(self._ring_layer) def OnSpinCenter(self, event): obj = event.EventObject name = obj.GetName() if name == "fast_ctrl": self._center[0] = obj.GetValue() elif name == "slow_ctrl": self._center[1] = obj.GetValue() self.DrawRings() def OnSpinCell(self, event): obj = event.EventObject name = obj.GetName() self._cell[self._cell_control_names.index(name)] = obj.GetValue() self.DrawRings() def OnSpin(self, event): self.DrawRings() def OnSpaceGroup(self, event): obj = event.EventObject self._spacegroup = obj.GetValue() self.DrawRings() def _draw_rings_layer(self, dc, data, map_rel): """Draw a points layer. dc the device context to draw on data an iterable of point tuples: (x, y, place, radius, colour, x_off, y_off, pdata) map_rel points relative to map if True, MUST BE TRUE for lightweight Assumes all points are the same colour, saving 100's of ms. """ assert map_rel is True if len(data) == 0: return (lon, lat, place, radius, colour, x_off, y_off, pdata) = data[0] scale = 2**self._pyslip.tiles.zoom_level # Draw points on map/view, using transparency if implemented. try: dc = wx.GCDC(dc) except NotImplementedError: pass dc.SetPen(wx.Pen(colour)) dc.SetBrush(wx.Brush(colour, wx.TRANSPARENT)) for (lon, lat, place, radius, colour, x_off, y_off, pdata) in data: (x, y) = self._pyslip.ConvertGeo2View((lon, lat)) dc.DrawCircle(x, y, radius * scale) def DrawRings(self): frame = self.GetParent().GetParent() try: uc = symmetry(unit_cell=self._cell, space_group_symbol=str(self._spacegroup)) hkl_list = cctbx.miller.build_set(uc, False, d_min=self.d_min_ctrl.GetValue()) except Exception as e: frame.update_statusbar(str(e)) return if self._show_hkl: hkl_list = hkl_list.common_set( cctbx.miller.set(crystal_symmetry=uc, indices=self._show_hkl, anomalous_flag=False)) frame.update_statusbar("%d %d %d %d %d %d, " % tuple(self._cell) + "number of indices: %d" % len(hkl_list.indices())) spacings = sorted(hkl_list.d_spacings(), key=lambda s: s[1], reverse=True) print("Printing spacings, len: %s" % len(spacings)) for d in spacings: print(d) detector = self._pyslip.tiles.raw_image.get_detector() wavelength = float(self.wavelength_ctrl.GetValue()) distance = float(self.distance_ctrl.GetValue()) pixel_size = detector[0].get_pixel_size( )[0] # FIXME assumes square pixels, and that all panels use same pixel size twotheta = hkl_list.two_theta(wavelength=wavelength) L_mm = [] L_pixels = [] for tt in twotheta: L_mm.append(distance * math.tan(tt[1])) for lmm in L_mm: L_pixels.append(lmm / pixel_size) xrayframe = self.GetParent().GetParent() panel_id, beam_pixel_fast, beam_pixel_slow = xrayframe.get_beam_center_px( ) ( beam_pixel_slow, beam_pixel_fast, ) = xrayframe.pyslip.tiles.flex_image.tile_readout_to_picture( panel_id, beam_pixel_slow - 0.5, beam_pixel_fast - 0.5) center = self._pyslip.tiles.picture_fast_slow_to_map_relative( beam_pixel_fast + self._center[0], beam_pixel_slow + self._center[1]) # XXX Transparency? ring_data = [(center[0], center[1], { "colour": "red", "radius": pxl }) for pxl in L_pixels] # Remove the old ring layer, and draw a new one. if hasattr(self, "_ring_layer") and self._ring_layer is not None: self._pyslip.DeleteLayer(self._ring_layer) self._ring_layer = None self._ring_layer = self._pyslip.AddPointLayer( ring_data, map_rel=True, visible=True, show_levels=[-3, -2, -1, 0, 1, 2, 3, 4, 5], renderer=self._draw_rings_layer, name="<ring_layer>", ) panel = detector[0] fast = col(panel.get_fast_axis()) slow = col(panel.get_slow_axis()) norm = col(panel.get_normal()) x = -panel.pixel_to_millimeter(self._center)[0] y = -panel.pixel_to_millimeter(self._center)[1] z = -(panel.get_distance() - distance) origin = (fast * x + slow * y + norm * z) + col(panel.get_origin()) self.origin.SetLabel("Panel 0 origin: %f, %f, %f" % origin.elems)
def draw_settings(self): for child in self.GetChildren(): if not isinstance(child, FloatSpin): # don't destroy FloatSpin controls otherwise bad things happen child.Destroy() sizer = self.GetSizer() if sizer is None: sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) sizer.Clear() # Put the border, d_min, d_max in an aligned grid box = wx.FlexGridSizer(cols=4, hgap=0, vgap=0) # border control if self.border_ctrl is None: self.border_ctrl = FloatSpin(self, digits=0, name="mask_border", min_val=0) box.Add(wx.StaticText(self, label="Border"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.border_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add(wx.StaticText(self, label="px"), 0, wx.ALIGN_CENTER_VERTICAL) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.border_ctrl) # Empty cell after border controls box.Add((0, 0)) # d_min control if self.params.masking.d_min is not None: self.d_min = self.params.masking.d_min else: self.d_min = 0 if self.d_min_ctrl is None: self.d_min_ctrl = FloatSpin( self, digits=2, name="d_min", value=self.d_min, min_val=0, increment=0.05, ) txtd = wx.StaticText(self, label="d_min") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.d_min_ctrl) # d_max control if self.params.masking.d_max is not None: self.d_max = self.params.masking.d_max else: self.d_max = 0 if self.d_max_ctrl is None: self.d_max_ctrl = FloatSpin( self, digits=2, name="d_max", value=self.d_max, min_val=0, increment=0.05, ) txtd = wx.StaticText(self, label="d_max") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.d_max_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.d_max_ctrl) sizer.Add(box) # resolution rings control grid = wx.FlexGridSizer( cols=2, rows=len(self.params.masking.resolution_range) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Resolution range:") grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for range_id, (d_min, d_max) in enumerate( self.params.masking.resolution_range): grid.Add(wx.StaticText(self, -1, "%.2f-%.2f" % (d_min, d_max))) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) self.Bind( wx.EVT_BUTTON, lambda evt, range_id=range_id: self.OnDeleteResolutionRange( evt, range_id=range_id), source=btn, ) self.resolution_range_d_min_ctrl = FloatCtrl( self, value=self._resolution_range_d_min, name="resolution_range_d_min") self.resolution_range_d_min_ctrl.SetMin(0) grid.Add( self.resolution_range_d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.resolution_range_d_max_ctrl = FloatCtrl( self, value=self._resolution_range_d_max, name="resolution_range_d_max") self.resolution_range_d_max_ctrl.SetMin(0) grid.Add( self.resolution_range_d_max_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) # empty cell # grid.Add(wx.StaticText(self, -1, ''), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.resolution_range_d_min_ctrl) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.resolution_range_d_max_ctrl) # ice rings control box = wx.BoxSizer(wx.HORIZONTAL) self.ice_rings_ctrl = wx.CheckBox(self, -1, "Ice rings") self.ice_rings_ctrl.SetValue(self.params.masking.ice_rings.filter) box.Add(self.ice_rings_ctrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_CHECKBOX, self.OnUpdate, self.ice_rings_ctrl) # ice rings d_min control if self.params.masking.ice_rings.d_min is not None: self.ice_rings_d_min = self.params.masking.ice_rings.d_min else: self.ice_rings_d_min = 0 if self.ice_rings_d_min_ctrl is None: self.ice_rings_d_min_ctrl = FloatSpin( self, digits=2, name="ice_rings_d_min", value=self.ice_rings_d_min, min_val=0, increment=0.05, ) txtd = wx.StaticText(self, label="d_min") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.ice_rings_d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.ice_rings_d_min_ctrl) # ice rings width control self.ice_rings_width = self.params.masking.ice_rings.width if self.ice_rings_width_ctrl is None: self.ice_rings_width_ctrl = FloatSpin( self, digits=3, name="ice_rings_width", value=self.ice_rings_width, min_val=0.001, increment=0.001, ) txtd = wx.StaticText(self, label="width") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.ice_rings_width_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.ice_rings_width_ctrl) sizer.Add(box) untrusted_rectangles = [] untrusted_polygons = [] untrusted_circles = [] # map index in self.params.masking.untrusted to index in above arrays self._rectangle_to_untrusted_id = [] self._polygon_to_untrusted_id = [] self._circle_to_untrusted_id = [] for i, untrusted in enumerate(self.params.masking.untrusted): if untrusted.rectangle is not None: untrusted_rectangles.append( (untrusted.panel, untrusted.rectangle)) self._rectangle_to_untrusted_id.append(i) elif untrusted.polygon is not None: untrusted_polygons.append((untrusted.panel, untrusted.polygon)) self._polygon_to_untrusted_id.append(i) elif untrusted.circle is not None: untrusted_circles.append((untrusted.panel, untrusted.circle)) self._circle_to_untrusted_id.append(i) # untrusted rectangles grid = wx.FlexGridSizer(cols=3, rows=len(untrusted_rectangles) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Panel:") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) text = wx.StaticText(self, -1, "Rectangle (x0, x1, y0, y1):") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for rect_id, (panel, rectangle) in enumerate(untrusted_rectangles): grid.Add(wx.StaticText(self, -1, "%i" % (panel))) grid.Add(wx.StaticText(self, -1, "%i %i %i %i" % tuple(rectangle))) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) untrusted_id = self._rectangle_to_untrusted_id[rect_id] self.Bind( wx.EVT_BUTTON, lambda evt, untrusted_id=untrusted_id: self. OnDeleteUntrustedRegion(evt, untrusted_id=untrusted_id), source=btn, ) self.untrusted_rectangle_panel_ctrl = IntCtrl( self, value=0, name="untrusted_rectangle_panel") grid.Add(self.untrusted_rectangle_panel_ctrl, 0, wx.ALL, 5) self.untrusted_rectangle_ctrl = StrCtrl(self, value="", name="untrusted_rectangle") grid.Add(self.untrusted_rectangle_ctrl, 0, wx.ALL, 5) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.untrusted_rectangle_ctrl) # untrusted polygons grid = wx.FlexGridSizer(cols=3, rows=len(untrusted_polygons) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Panel:") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) text = wx.StaticText(self, -1, "Polygons (x1, y1, ..., xn, yn):") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for polygon_id, (panel, polygon) in enumerate(untrusted_polygons): grid.Add(StrCtrl(self, value="%i" % (panel), style=wx.TE_READONLY), 0, wx.ALL, 5) grid.Add( StrCtrl( self, value=" ".join(["%i"] * len(polygon)) % tuple(polygon), style=wx.TE_READONLY, ), 0, wx.ALL, 5, ) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) untrusted_id = self._polygon_to_untrusted_id[polygon_id] self.Bind( wx.EVT_BUTTON, lambda evt, untrusted_id=untrusted_id: self. OnDeleteUntrustedRegion(evt, untrusted_id=untrusted_id), source=btn, ) self.untrusted_polygon_panel_ctrl = IntCtrl( self, value=0, name="untrusted_polygon_panel") grid.Add(self.untrusted_polygon_panel_ctrl, 0, wx.ALL, 5) self.untrusted_polygon_ctrl = StrCtrl(self, value="", name="untrusted_polygon") grid.Add(self.untrusted_polygon_ctrl, 0, wx.ALL, 5) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.untrusted_polygon_ctrl) # untrusted circles grid = wx.FlexGridSizer(cols=3, rows=len(untrusted_circles) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Panel:") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) text = wx.StaticText(self, -1, "Circle (x, y, r):") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for circle_id, (panel, circle) in enumerate(untrusted_circles): grid.Add(wx.StaticText(self, -1, "%i" % (panel))) grid.Add(wx.StaticText(self, -1, "%i %i %i" % tuple(circle))) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) untrusted_id = self._circle_to_untrusted_id[circle_id] self.Bind( wx.EVT_BUTTON, lambda evt, untrusted_id=untrusted_id: self. OnDeleteUntrustedRegion(evt, untrusted_id=untrusted_id), source=btn, ) self.untrusted_circle_panel_ctrl = IntCtrl( self, value=0, name="untrusted_circle_panel") grid.Add(self.untrusted_circle_panel_ctrl, 0, wx.ALL, 5) self.untrusted_circle_ctrl = StrCtrl(self, value="", name="untrusted_circle") grid.Add(self.untrusted_circle_ctrl, 0, wx.ALL, 5) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.untrusted_circle_ctrl) # Draw rectangle/circle mode buttons grid = wx.FlexGridSizer(cols=4, rows=1, vgap=0, hgap=0) sizer.Add(grid) grid.Add(wx.StaticText(self, label="Mode:")) self.mode_rectangle_button = wx.ToggleButton(self, -1, "Rectangle") self.mode_rectangle_button.SetValue(self._mode_rectangle) grid.Add(self.mode_rectangle_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_TOGGLEBUTTON, self.OnUpdate, self.mode_rectangle_button) self.mode_circle_button = wx.ToggleButton(self, -1, "Circle") self.mode_circle_button.SetValue(self._mode_circle) grid.Add(self.mode_circle_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_TOGGLEBUTTON, self.OnUpdate, self.mode_circle_button) self.mode_polygon_button = wx.ToggleButton(self, -1, "Polygon") self.mode_polygon_button.SetValue(self._mode_polygon) grid.Add(self.mode_polygon_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_TOGGLEBUTTON, self.OnUpdate, self.mode_polygon_button) # show/save mask controls grid = wx.FlexGridSizer(cols=3, rows=2, vgap=0, hgap=0) sizer.Add(grid) self.show_mask_ctrl = wx.CheckBox(self, -1, "Show mask") self.show_mask_ctrl.SetValue(self.params.show_mask) grid.Add(self.show_mask_ctrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_CHECKBOX, self.OnUpdate, self.show_mask_ctrl) self.save_mask_button = wx.Button(self, -1, "Save mask") grid.Add(self.save_mask_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_BUTTON, self.OnSaveMask, self.save_mask_button) self.save_mask_txt_ctrl = StrCtrl(self, value=self.params.output.mask, name="mask_pickle") grid.Add(self.save_mask_txt_ctrl, 0, wx.ALL, 5) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.save_mask_txt_ctrl) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.save_params_button = wx.Button(self, -1, "Save") grid.Add(self.save_params_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_BUTTON, self.OnSaveMaskParams, self.save_params_button) self.save_params_txt_ctrl = StrCtrl( self, value=self.params.output.mask_params, name="mask_phil") grid.Add(self.save_params_txt_ctrl, 0, wx.ALL, 5) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.save_params_txt_ctrl) sizer.Layout() sizer.Fit(self)
def add_extra_controls(self, root, parentpanel, extra_buttons=None, mini_mode=False): standalone_mode = extra_buttons is not None base_line = 1 if standalone_mode else 2 if standalone_mode: gauges_base_line = base_line + 10 elif mini_mode and root.display_graph: gauges_base_line = base_line + 6 else: gauges_base_line = base_line + 5 tempdisp_line = gauges_base_line + (2 if root.display_gauges else 0) if mini_mode and root.display_graph: e_base_line = base_line + 3 else: e_base_line = base_line + 2 pos_mapping = { "htemp_label": (base_line + 0, 0), "htemp_off": (base_line + 0, 2), "htemp_val": (base_line + 0, 3), "htemp_set": (base_line + 0, 4), "btemp_label": (base_line + 1, 0), "btemp_off": (base_line + 1, 2), "btemp_val": (base_line + 1, 3), "btemp_set": (base_line + 1, 4), "ebuttons": (e_base_line + 0, 0), "esettings": (e_base_line + 1, 0), "speedcontrol": (e_base_line + 2, 0), "htemp_gauge": (gauges_base_line + 0, 0), "btemp_gauge": (gauges_base_line + 1, 0), "tempdisp": (tempdisp_line, 0), "extrude": (3, 0), "reverse": (3, 2), } span_mapping = { "htemp_label": (1, 2), "htemp_off": (1, 1), "htemp_val": (1, 1), "htemp_set": (1, 1 if root.display_graph else 2), "btemp_label": (1, 2), "btemp_off": (1, 1), "btemp_val": (1, 1), "btemp_set": (1, 1 if root.display_graph else 2), "ebuttons": (1, 5 if root.display_graph else 6), "esettings": (1, 5 if root.display_graph else 6), "speedcontrol": (1, 5 if root.display_graph else 6), "htemp_gauge": (1, 5 if mini_mode else 6), "btemp_gauge": (1, 5 if mini_mode else 6), "tempdisp": (1, 5 if mini_mode else 6), "extrude": (1, 2), "reverse": (1, 3), } if standalone_mode: pos_mapping["tempgraph"] = (base_line + 5, 0) span_mapping["tempgraph"] = (5, 6) elif mini_mode: pos_mapping["tempgraph"] = (base_line + 2, 0) span_mapping["tempgraph"] = (1, 5) else: pos_mapping["tempgraph"] = (base_line + 0, 5) span_mapping["tempgraph"] = (5, 1) if mini_mode: pos_mapping["etool_label"] = (0, 0) pos_mapping["etool_val"] = (0, 1) pos_mapping["edist_label"] = (0, 2) pos_mapping["edist_val"] = (0, 3) pos_mapping["edist_unit"] = (0, 4) else: pos_mapping["edist_label"] = (0, 0) pos_mapping["edist_val"] = (1, 0) pos_mapping["edist_unit"] = (1, 1) pos_mapping["efeed_label"] = (0, 2) pos_mapping["efeed_val"] = (1, 2) pos_mapping["efeed_unit"] = (1, 3) def add(name, widget, *args, **kwargs): kwargs["pos"] = pos_mapping[name] if name in span_mapping: kwargs["span"] = span_mapping[name] if "container" in kwargs: container = kwargs["container"] del kwargs["container"] else: container = self container.Add(widget, *args, **kwargs) # Hotend & bed temperatures # # Hotend temp add("htemp_label", wx.StaticText(parentpanel, -1, _("Heat:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) htemp_choices = [ root.temps[i] + " (" + i + ")" for i in sorted(root.temps.keys(), key=lambda x: root.temps[x]) ] root.settoff = make_button(parentpanel, _("Off"), lambda e: root.do_settemp("off"), _("Switch Hotend Off"), size=(38, -1), style=wx.BU_EXACTFIT) root.printerControls.append(root.settoff) add("htemp_off", root.settoff) if root.settings.last_temperature not in map(float, root.temps.values()): htemp_choices = [str(root.settings.last_temperature)] + htemp_choices root.htemp = wx.ComboBox(parentpanel, -1, choices=htemp_choices, style=wx.CB_DROPDOWN, size=(80, -1)) root.htemp.SetToolTip(wx.ToolTip(_("Select Temperature for Hotend"))) root.htemp.Bind(wx.EVT_COMBOBOX, root.htemp_change) add("htemp_val", root.htemp) root.settbtn = make_button(parentpanel, _("Set"), root.do_settemp, _("Switch Hotend On"), size=(38, -1), style=wx.BU_EXACTFIT) root.printerControls.append(root.settbtn) add("htemp_set", root.settbtn, flag=wx.EXPAND) # Bed temp add("btemp_label", wx.StaticText(parentpanel, -1, _("Bed:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) btemp_choices = [ root.bedtemps[i] + " (" + i + ")" for i in sorted(root.bedtemps.keys(), key=lambda x: root.temps[x]) ] root.setboff = make_button(parentpanel, _("Off"), lambda e: root.do_bedtemp("off"), _("Switch Heated Bed Off"), size=(38, -1), style=wx.BU_EXACTFIT) root.printerControls.append(root.setboff) add("btemp_off", root.setboff) if root.settings.last_bed_temperature not in map(float, root.bedtemps.values()): btemp_choices = [str(root.settings.last_bed_temperature) ] + btemp_choices root.btemp = wx.ComboBox(parentpanel, -1, choices=btemp_choices, style=wx.CB_DROPDOWN, size=(80, -1)) root.btemp.SetToolTip(wx.ToolTip(_("Select Temperature for Heated Bed"))) root.btemp.Bind(wx.EVT_COMBOBOX, root.btemp_change) add("btemp_val", root.btemp) root.setbbtn = make_button(parentpanel, _("Set"), root.do_bedtemp, _("Switch Heated Bed On"), size=(38, -1), style=wx.BU_EXACTFIT) root.printerControls.append(root.setbbtn) add("btemp_set", root.setbbtn, flag=wx.EXPAND) root.btemp.SetValue(str(root.settings.last_bed_temperature)) root.htemp.SetValue(str(root.settings.last_temperature)) # added for an error where only the bed would get (pla) or (abs). # This ensures, if last temp is a default pla or abs, it will be marked so. # if it is not, then a (user) remark is added. This denotes a manual entry for i in btemp_choices: if i.split()[0] == str(root.settings.last_bed_temperature).split( '.')[0] or i.split()[0] == str( root.settings.last_bed_temperature): root.btemp.SetValue(i) for i in htemp_choices: if i.split()[0] == str(root.settings.last_temperature).split( '.')[0] or i.split()[0] == str(root.settings.last_temperature): root.htemp.SetValue(i) if '(' not in root.btemp.Value: root.btemp.SetValue(root.btemp.Value + ' (user)') if '(' not in root.htemp.Value: root.htemp.SetValue(root.htemp.Value + ' (user)') # Speed control # speedpanel = root.newPanel(parentpanel) speedsizer = wx.BoxSizer(wx.HORIZONTAL) speedsizer.Add(wx.StaticText(speedpanel, -1, _("Print speed:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) root.speed_slider = wx.Slider(speedpanel, -1, 100, 1, 300) speedsizer.Add(root.speed_slider, 1, flag=wx.EXPAND) root.speed_spin = FloatSpin(speedpanel, -1, value=100, min_val=1, max_val=300, digits=0, style=wx.ALIGN_LEFT, size=(80, -1)) speedsizer.Add(root.speed_spin, 0, flag=wx.ALIGN_CENTER_VERTICAL) root.speed_label = wx.StaticText(speedpanel, -1, _("%")) speedsizer.Add(root.speed_label, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) def speedslider_set(event): root.do_setspeed() root.speed_setbtn.SetBackgroundColour(wx.NullColour) root.speed_setbtn = make_button(speedpanel, _("Set"), speedslider_set, _("Set print speed factor"), size=(38, -1), style=wx.BU_EXACTFIT) root.printerControls.append(root.speed_setbtn) speedsizer.Add(root.speed_setbtn, flag=wx.ALIGN_CENTER) speedpanel.SetSizer(speedsizer) add("speedcontrol", speedpanel, flag=wx.EXPAND) def speedslider_spin(event): value = root.speed_spin.GetValue() root.speed_setbtn.SetBackgroundColour("red") root.speed_slider.SetValue(value) root.speed_spin.Bind(wx.EVT_SPINCTRL, speedslider_spin) def speedslider_scroll(event): value = root.speed_slider.GetValue() root.speed_setbtn.SetBackgroundColour("red") root.speed_spin.SetValue(value) root.speed_slider.Bind(wx.EVT_SCROLL, speedslider_scroll) # Temperature gauges # if root.display_gauges: root.hottgauge = TempGauge(parentpanel, size=(-1, 24), title=_("Heater:"), maxval=300, bgcolor=root.bgcolor) add("htemp_gauge", root.hottgauge, flag=wx.EXPAND) root.bedtgauge = TempGauge(parentpanel, size=(-1, 24), title=_("Bed:"), maxval=150, bgcolor=root.bgcolor) add("btemp_gauge", root.bedtgauge, flag=wx.EXPAND) def hotendgauge_scroll_setpoint(e): rot = e.GetWheelRotation() if rot > 0: root.do_settemp(str(root.hsetpoint + 1)) elif rot < 0: root.do_settemp(str(max(0, root.hsetpoint - 1))) def bedgauge_scroll_setpoint(e): rot = e.GetWheelRotation() if rot > 0: root.do_settemp(str(root.bsetpoint + 1)) elif rot < 0: root.do_settemp(str(max(0, root.bsetpoint - 1))) root.hottgauge.Bind(wx.EVT_MOUSEWHEEL, hotendgauge_scroll_setpoint) root.bedtgauge.Bind(wx.EVT_MOUSEWHEEL, bedgauge_scroll_setpoint) # Temperature (M105) feedback display # root.tempdisp = wx.StaticText(parentpanel, -1, "", style=wx.ST_NO_AUTORESIZE) def on_tempdisp_size(evt): root.tempdisp.Wrap(root.tempdisp.GetSize().width) root.tempdisp.Bind(wx.EVT_SIZE, on_tempdisp_size) def tempdisp_setlabel(label): wx.StaticText.SetLabel(root.tempdisp, label) root.tempdisp.Wrap(root.tempdisp.GetSize().width) root.tempdisp.SetSize((-1, root.tempdisp.GetBestSize().height)) root.tempdisp.SetLabel = tempdisp_setlabel add("tempdisp", root.tempdisp, flag=wx.EXPAND) # Temperature graph # if root.display_graph: root.graph = Graph(parentpanel, wx.ID_ANY, root) add("tempgraph", root.graph, flag=wx.EXPAND | wx.ALL, border=5) root.graph.Bind(wx.EVT_LEFT_DOWN, root.graph.show_graph_window) # Extrusion controls # # Extrusion settings esettingspanel = root.newPanel(parentpanel) esettingssizer = wx.GridBagSizer() esettingssizer.SetEmptyCellSize((0, 0)) root.edist = FloatSpin(esettingspanel, -1, value=root.settings.last_extrusion, min_val=0, max_val=1000, size=(90, -1), digits=1) root.edist.SetBackgroundColour((225, 200, 200)) root.edist.SetForegroundColour("black") root.edist.Bind(wx.EVT_SPINCTRL, root.setfeeds) root.edist.Bind(wx.EVT_TEXT, root.setfeeds) add("edist_label", wx.StaticText(esettingspanel, -1, _("Length:")), container=esettingssizer, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, border=5) add("edist_val", root.edist, container=esettingssizer, flag=wx.ALIGN_CENTER | wx.RIGHT, border=5) unit_label = _("mm") if mini_mode else _("mm @") add("edist_unit", wx.StaticText(esettingspanel, -1, unit_label), container=esettingssizer, flag=wx.ALIGN_CENTER | wx.RIGHT, border=5) root.edist.SetToolTip(wx.ToolTip(_("Amount to Extrude or Retract (mm)"))) if not mini_mode: root.efeedc = FloatSpin(esettingspanel, -1, value=root.settings.e_feedrate, min_val=0, max_val=50000, size=(90, -1), digits=1) root.efeedc.SetToolTip( wx.ToolTip(_("Extrude / Retract speed (mm/min)"))) root.efeedc.SetBackgroundColour((225, 200, 200)) root.efeedc.SetForegroundColour("black") root.efeedc.Bind(wx.EVT_SPINCTRL, root.setfeeds) root.efeedc.Bind(wx.EVT_TEXT, root.setfeeds) add("efeed_val", root.efeedc, container=esettingssizer, flag=wx.ALIGN_CENTER | wx.RIGHT, border=5) add("efeed_label", wx.StaticText(esettingspanel, -1, _("Speed:")), container=esettingssizer, flag=wx.ALIGN_LEFT) add("efeed_unit", wx.StaticText(esettingspanel, -1, _("mm/\nmin")), container=esettingssizer, flag=wx.ALIGN_CENTER) else: root.efeedc = None esettingspanel.SetSizer(esettingssizer) add("esettings", esettingspanel, flag=wx.ALIGN_LEFT) if not standalone_mode: ebuttonspanel = root.newPanel(parentpanel) ebuttonssizer = wx.BoxSizer(wx.HORIZONTAL) if root.settings.extruders > 1: etool_sel_panel = esettingspanel if mini_mode else ebuttonspanel etool_label = wx.StaticText(etool_sel_panel, -1, _("Tool:")) if root.settings.extruders == 2: root.extrudersel = wx.Button(etool_sel_panel, -1, "0", style=wx.BU_EXACTFIT) root.extrudersel.SetToolTip( wx.ToolTip(_("Click to switch current extruder"))) def extrudersel_cb(event): if root.extrudersel.GetLabel() == "1": new = "0" else: new = "1" root.extrudersel.SetLabel(new) root.tool_change(event) root.extrudersel.Bind(wx.EVT_BUTTON, extrudersel_cb) root.extrudersel.GetValue = root.extrudersel.GetLabel root.extrudersel.SetValue = root.extrudersel.SetLabel else: choices = [str(i) for i in range(0, root.settings.extruders)] root.extrudersel = wx.ComboBox(etool_sel_panel, -1, choices=choices, style=wx.CB_DROPDOWN | wx.CB_READONLY, size=(50, -1)) root.extrudersel.SetToolTip( wx.ToolTip(_("Select current extruder"))) root.extrudersel.SetValue(choices[0]) root.extrudersel.Bind(wx.EVT_COMBOBOX, root.tool_change) root.printerControls.append(root.extrudersel) if mini_mode: add("etool_label", etool_label, container=esettingssizer, flag=wx.ALIGN_CENTER) add("etool_val", root.extrudersel, container=esettingssizer) else: ebuttonssizer.Add(etool_label, flag=wx.ALIGN_CENTER) ebuttonssizer.Add(root.extrudersel) for key in ["extrude", "reverse"]: desc = root.cpbuttons[key] btn = make_custom_button(root, ebuttonspanel, desc, style=wx.BU_EXACTFIT) ebuttonssizer.Add(btn, 1, flag=wx.EXPAND) ebuttonspanel.SetSizer(ebuttonssizer) add("ebuttons", ebuttonspanel, flag=wx.EXPAND) else: for key, btn in extra_buttons.items(): add(key, btn, flag=wx.EXPAND)
class TransformDialog(wx.Dialog): def __init__(self, parent, name, selected, bone_list, *args, **kw): super().__init__(parent, *args, **kw) self.selected = selected self.SetTitle("Set {} for Animation".format(name)) grid_sizer = wx.FlexGridSizer(rows=4, cols=2, hgap=10, vgap=10) if bone_list: self.bone_list = wx.Choice(self, -1, choices=bone_list) for i, bone_name in enumerate(bone_list): if 'b_c_base' in bone_name.lower(): self.bone_list.Select(i) break else: self.bone_list.Select(0) grid_sizer.Add(wx.StaticText(self, -1, 'Bone'), 0, wx.CENTER) grid_sizer.Add(self.bone_list, 0, wx.ALIGN_RIGHT) else: self.bone_list = None grid_sizer.Add(wx.StaticText(self, -1, f'X {name}'), 0, wx.CENTER) self.ctrl_x = FloatSpin(self, -1, increment=0.01, value=0.0, digits=8, size=(150, -1)) grid_sizer.Add(self.ctrl_x, 0, wx.ALIGN_RIGHT) grid_sizer.Add(wx.StaticText(self, -1, f'Y {name}'), 0, wx.CENTER) self.ctrl_y = FloatSpin(self, -1, increment=0.01, value=0.0, digits=8, size=(150, -1)) grid_sizer.Add(self.ctrl_y, 0, wx.ALIGN_RIGHT) grid_sizer.Add(wx.StaticText(self, -1, f'Z {name}'), 0, wx.CENTER) self.ctrl_z = FloatSpin(self, -1, increment=0.01, value=0.0, digits=8, size=(150, -1)) grid_sizer.Add(self.ctrl_z, 0, wx.ALIGN_RIGHT) ok_button = wx.Button(self, wx.ID_OK, "Ok") ok_button.SetDefault() cancel_button = wx.Button(self, wx.ID_CANCEL, "Cancel") hsizer = wx.BoxSizer(wx.HORIZONTAL) hsizer.Add(grid_sizer, 1, wx.ALL, 10) button_sizer = wx.BoxSizer(wx.HORIZONTAL) button_sizer.Add(ok_button, 0, wx.LEFT | wx.RIGHT, 2) button_sizer.Add(cancel_button, 0, wx.LEFT | wx.RIGHT, 5) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(hsizer, 1, wx.ALL, 10) sizer.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 10) sizer.Add(button_sizer, 0, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 10) self.Bind(wx.EVT_BUTTON, self.on_close) self.ctrl_x.SetFocus() self.SetSizer(sizer) sizer.Fit(self) self.Layout() def on_close(self, e): if e.GetId() == wx.ID_OK and self.bone_list and self.bone_list.GetSelection() == wx.NOT_FOUND: with wx.MessageDialog(self, " No Bone Selected", "Warning", wx.OK) as dlg: dlg.ShowModal() # Shows it return e.Skip() def GetBoneIndex(self): if not self.bone_list: return wx.NOT_FOUND return self.bone_list.GetSelection() def GetValues(self): return self.ctrl_x.GetValue(), self.ctrl_y.GetValue(), self.ctrl_z.GetValue()
class MaskSettingsPanel(wx.Panel): def __init__(self, *args, **kwds): super(MaskSettingsPanel, self).__init__(*args, **kwds) self.params = args[0].phil_params self._pyslip = self.GetParent().GetParent().pyslip self.border_ctrl = None self.d_min_ctrl = None self.d_max_ctrl = None self.resolution_range_d_min_ctrl = None self.resolution_range_d_max_ctrl = None self.ice_rings_d_min_ctrl = None self.ice_rings_width_ctrl = None self._mode_rectangle_layer = None self._mode_polygon_layer = None self._mode_circle_layer = None self._rectangle_x0y0 = None self._rectangle_x1y1 = None self._mode_rectangle = False self._mode_polygon = False self._mode_polygon_points = [] self._mode_circle = False self._resolution_range_d_min = 0 self._resolution_range_d_max = 0 self._pyslip.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self._pyslip.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self._pyslip.Bind(wx.EVT_MOTION, self.OnMove) self.draw_settings() self.UpdateMask() def __del__(self): if self._mode_rectangle_layer: self._pyslip.DeleteLayer(self._mode_rectangle_layer) if self._mode_polygon_layer: self._pyslip.DeleteLayer(self._mode_polygon_layer) if self._mode_circle_layer: self._pyslip.DeleteLayer(self._mode_circle_layer) self._pyslip.Unbind(wx.EVT_LEFT_DOWN, handler=self.OnLeftDown) self._pyslip.Unbind(wx.EVT_LEFT_UP, handler=self.OnLeftUp) self._pyslip.Unbind(wx.EVT_MOTION, handler=self.OnMove) def draw_settings(self): for child in self.GetChildren(): if not isinstance(child, FloatSpin): # don't destroy FloatSpin controls otherwise bad things happen child.Destroy() sizer = self.GetSizer() if sizer is None: sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) sizer.Clear() # Put the border, d_min, d_max in an aligned grid box = wx.FlexGridSizer(cols=4, hgap=0, vgap=0) # border control if self.border_ctrl is None: self.border_ctrl = FloatSpin(self, digits=0, name="mask_border", min_val=0) box.Add(wx.StaticText(self, label="Border"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.border_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add(wx.StaticText(self, label="px"), 0, wx.ALIGN_CENTER_VERTICAL) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.border_ctrl) # Empty cell after border controls box.Add((0, 0)) # d_min control if self.params.masking.d_min is not None: self.d_min = self.params.masking.d_min else: self.d_min = 0 if self.d_min_ctrl is None: self.d_min_ctrl = FloatSpin( self, digits=2, name="d_min", value=self.d_min, min_val=0, increment=0.05, ) txtd = wx.StaticText(self, label="d_min") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.d_min_ctrl) # d_max control if self.params.masking.d_max is not None: self.d_max = self.params.masking.d_max else: self.d_max = 0 if self.d_max_ctrl is None: self.d_max_ctrl = FloatSpin( self, digits=2, name="d_max", value=self.d_max, min_val=0, increment=0.05, ) txtd = wx.StaticText(self, label="d_max") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.d_max_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.d_max_ctrl) sizer.Add(box) # resolution rings control grid = wx.FlexGridSizer( cols=2, rows=len(self.params.masking.resolution_range) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Resolution range:") grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for range_id, (d_min, d_max) in enumerate( self.params.masking.resolution_range): grid.Add(wx.StaticText(self, -1, "%.2f-%.2f" % (d_min, d_max))) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) self.Bind( wx.EVT_BUTTON, lambda evt, range_id=range_id: self.OnDeleteResolutionRange( evt, range_id=range_id), source=btn, ) self.resolution_range_d_min_ctrl = FloatCtrl( self, value=self._resolution_range_d_min, name="resolution_range_d_min") self.resolution_range_d_min_ctrl.SetMin(0) grid.Add( self.resolution_range_d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.resolution_range_d_max_ctrl = FloatCtrl( self, value=self._resolution_range_d_max, name="resolution_range_d_max") self.resolution_range_d_max_ctrl.SetMin(0) grid.Add( self.resolution_range_d_max_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) # empty cell # grid.Add(wx.StaticText(self, -1, ''), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.resolution_range_d_min_ctrl) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.resolution_range_d_max_ctrl) # ice rings control box = wx.BoxSizer(wx.HORIZONTAL) self.ice_rings_ctrl = wx.CheckBox(self, -1, "Ice rings") self.ice_rings_ctrl.SetValue(self.params.masking.ice_rings.filter) box.Add(self.ice_rings_ctrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_CHECKBOX, self.OnUpdate, self.ice_rings_ctrl) # ice rings d_min control if self.params.masking.ice_rings.d_min is not None: self.ice_rings_d_min = self.params.masking.ice_rings.d_min else: self.ice_rings_d_min = 0 if self.ice_rings_d_min_ctrl is None: self.ice_rings_d_min_ctrl = FloatSpin( self, digits=2, name="ice_rings_d_min", value=self.ice_rings_d_min, min_val=0, increment=0.05, ) txtd = wx.StaticText(self, label="d_min") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.ice_rings_d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.ice_rings_d_min_ctrl) # ice rings width control self.ice_rings_width = self.params.masking.ice_rings.width if self.ice_rings_width_ctrl is None: self.ice_rings_width_ctrl = FloatSpin( self, digits=3, name="ice_rings_width", value=self.ice_rings_width, min_val=0.001, increment=0.001, ) txtd = wx.StaticText(self, label="width") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add( self.ice_rings_width_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnUpdate, self.ice_rings_width_ctrl) sizer.Add(box) untrusted_rectangles = [] untrusted_polygons = [] untrusted_circles = [] # map index in self.params.masking.untrusted to index in above arrays self._rectangle_to_untrusted_id = [] self._polygon_to_untrusted_id = [] self._circle_to_untrusted_id = [] for i, untrusted in enumerate(self.params.masking.untrusted): if untrusted.rectangle is not None: untrusted_rectangles.append( (untrusted.panel, untrusted.rectangle)) self._rectangle_to_untrusted_id.append(i) elif untrusted.polygon is not None: untrusted_polygons.append((untrusted.panel, untrusted.polygon)) self._polygon_to_untrusted_id.append(i) elif untrusted.circle is not None: untrusted_circles.append((untrusted.panel, untrusted.circle)) self._circle_to_untrusted_id.append(i) # untrusted rectangles grid = wx.FlexGridSizer(cols=3, rows=len(untrusted_rectangles) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Panel:") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) text = wx.StaticText(self, -1, "Rectangle (x0, x1, y0, y1):") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for rect_id, (panel, rectangle) in enumerate(untrusted_rectangles): grid.Add(wx.StaticText(self, -1, "%i" % (panel))) grid.Add(wx.StaticText(self, -1, "%i %i %i %i" % tuple(rectangle))) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) untrusted_id = self._rectangle_to_untrusted_id[rect_id] self.Bind( wx.EVT_BUTTON, lambda evt, untrusted_id=untrusted_id: self. OnDeleteUntrustedRegion(evt, untrusted_id=untrusted_id), source=btn, ) self.untrusted_rectangle_panel_ctrl = IntCtrl( self, value=0, name="untrusted_rectangle_panel") grid.Add(self.untrusted_rectangle_panel_ctrl, 0, wx.ALL, 5) self.untrusted_rectangle_ctrl = StrCtrl(self, value="", name="untrusted_rectangle") grid.Add(self.untrusted_rectangle_ctrl, 0, wx.ALL, 5) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.untrusted_rectangle_ctrl) # untrusted polygons grid = wx.FlexGridSizer(cols=3, rows=len(untrusted_polygons) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Panel:") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) text = wx.StaticText(self, -1, "Polygons (x1, y1, ..., xn, yn):") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for polygon_id, (panel, polygon) in enumerate(untrusted_polygons): grid.Add(StrCtrl(self, value="%i" % (panel), style=wx.TE_READONLY), 0, wx.ALL, 5) grid.Add( StrCtrl( self, value=" ".join(["%i"] * len(polygon)) % tuple(polygon), style=wx.TE_READONLY, ), 0, wx.ALL, 5, ) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) untrusted_id = self._polygon_to_untrusted_id[polygon_id] self.Bind( wx.EVT_BUTTON, lambda evt, untrusted_id=untrusted_id: self. OnDeleteUntrustedRegion(evt, untrusted_id=untrusted_id), source=btn, ) self.untrusted_polygon_panel_ctrl = IntCtrl( self, value=0, name="untrusted_polygon_panel") grid.Add(self.untrusted_polygon_panel_ctrl, 0, wx.ALL, 5) self.untrusted_polygon_ctrl = StrCtrl(self, value="", name="untrusted_polygon") grid.Add(self.untrusted_polygon_ctrl, 0, wx.ALL, 5) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.untrusted_polygon_ctrl) # untrusted circles grid = wx.FlexGridSizer(cols=3, rows=len(untrusted_circles) + 2, vgap=0, hgap=0) sizer.Add(grid) text = wx.StaticText(self, -1, "Panel:") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) text = wx.StaticText(self, -1, "Circle (x, y, r):") text.GetFont().SetWeight(wx.BOLD) grid.Add(text) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) for circle_id, (panel, circle) in enumerate(untrusted_circles): grid.Add(wx.StaticText(self, -1, "%i" % (panel))) grid.Add(wx.StaticText(self, -1, "%i %i %i" % tuple(circle))) btn = metallicbutton.MetallicButton( parent=self, label="delete", bmp=wxtbx.bitmaps.fetch_icon_bitmap("actions", "cancel", 16), ) grid.Add(btn) untrusted_id = self._circle_to_untrusted_id[circle_id] self.Bind( wx.EVT_BUTTON, lambda evt, untrusted_id=untrusted_id: self. OnDeleteUntrustedRegion(evt, untrusted_id=untrusted_id), source=btn, ) self.untrusted_circle_panel_ctrl = IntCtrl( self, value=0, name="untrusted_circle_panel") grid.Add(self.untrusted_circle_panel_ctrl, 0, wx.ALL, 5) self.untrusted_circle_ctrl = StrCtrl(self, value="", name="untrusted_circle") grid.Add(self.untrusted_circle_ctrl, 0, wx.ALL, 5) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.untrusted_circle_ctrl) # Draw rectangle/circle mode buttons grid = wx.FlexGridSizer(cols=4, rows=1, vgap=0, hgap=0) sizer.Add(grid) grid.Add(wx.StaticText(self, label="Mode:")) self.mode_rectangle_button = wx.ToggleButton(self, -1, "Rectangle") self.mode_rectangle_button.SetValue(self._mode_rectangle) grid.Add(self.mode_rectangle_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_TOGGLEBUTTON, self.OnUpdate, self.mode_rectangle_button) self.mode_circle_button = wx.ToggleButton(self, -1, "Circle") self.mode_circle_button.SetValue(self._mode_circle) grid.Add(self.mode_circle_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_TOGGLEBUTTON, self.OnUpdate, self.mode_circle_button) self.mode_polygon_button = wx.ToggleButton(self, -1, "Polygon") self.mode_polygon_button.SetValue(self._mode_polygon) grid.Add(self.mode_polygon_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_TOGGLEBUTTON, self.OnUpdate, self.mode_polygon_button) # show/save mask controls grid = wx.FlexGridSizer(cols=3, rows=2, vgap=0, hgap=0) sizer.Add(grid) self.show_mask_ctrl = wx.CheckBox(self, -1, "Show mask") self.show_mask_ctrl.SetValue(self.params.show_mask) grid.Add(self.show_mask_ctrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_CHECKBOX, self.OnUpdate, self.show_mask_ctrl) self.save_mask_button = wx.Button(self, -1, "Save mask") grid.Add(self.save_mask_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_BUTTON, self.OnSaveMask, self.save_mask_button) self.save_mask_txt_ctrl = StrCtrl(self, value=self.params.output.mask, name="mask_pickle") grid.Add(self.save_mask_txt_ctrl, 0, wx.ALL, 5) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.save_mask_txt_ctrl) # empty cell grid.Add(wx.StaticText(self, -1, ""), 0, wx.EXPAND) self.save_params_button = wx.Button(self, -1, "Save") grid.Add(self.save_params_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_BUTTON, self.OnSaveMaskParams, self.save_params_button) self.save_params_txt_ctrl = StrCtrl( self, value=self.params.output.mask_params, name="mask_phil") grid.Add(self.save_params_txt_ctrl, 0, wx.ALL, 5) self.Bind(EVT_PHIL_CONTROL, self.OnUpdate, self.save_params_txt_ctrl) sizer.Layout() sizer.Fit(self) def OnDeleteUntrustedRegion(self, event, untrusted_id): if untrusted_id is not None: del self.params.masking.untrusted[untrusted_id] self.OnUpdate(event) def OnDeleteResolutionRange(self, event, range_id): if range_id is not None: del self.params.masking.resolution_range[range_id] self.OnUpdate(event) def OnUpdate(self, event): image_viewer_frame = self.GetParent().GetParent() self.params.show_mask = self.show_mask_ctrl.GetValue() # untidy image_viewer_frame.settings.show_mask = self.params.show_mask image_viewer_frame.params.show_mask = self.params.show_mask image_viewer_frame.settings_frame.panel.show_mask.SetValue( self.params.show_mask) self.params.output.mask = self.save_mask_txt_ctrl.GetValue() self.params.output.mask_params = self.save_params_txt_ctrl.GetValue() if self._mode_polygon and (not self.mode_polygon_button.GetValue() or self.mode_circle_button.GetValue() or self.mode_rectangle_button.GetValue()): self.AddUntrustedPolygon(self._mode_polygon_points) self._mode_polygon_points = [] self._pyslip.DeleteLayer(self._mode_polygon_layer) self._mode_polygon_layer = None if self.mode_rectangle_button.GetValue(): if not self._mode_rectangle: # mode wasn't set but button has been pressed, so set mode self._mode_rectangle = True # set other modes and buttons to False self._mode_circle = False self.mode_circle_button.SetValue(False) self._mode_polygon = False self.mode_polygon_button.SetValue(False) if self.mode_circle_button.GetValue(): if not self._mode_circle: # mode wasn't set but button has been pressed, so set mode self._mode_circle = True # set other modes and buttons to False self._mode_rectangle = False self.mode_rectangle_button.SetValue(False) self._mode_polygon = False self.mode_polygon_button.SetValue(False) if self.mode_polygon_button.GetValue(): if not self._mode_polygon: # mode wasn't set but button has been pressed, so set mode self._mode_polygon = True # set other modes and buttons to False self._mode_rectangle = False self.mode_rectangle_button.SetValue(False) self._mode_circle = False self.mode_circle_button.SetValue(False) if not (self.mode_circle_button.GetValue() or self.mode_rectangle_button.GetValue() or self.mode_polygon_button.GetValue()): self._mode_circle = False self._mode_rectangle = False self._mode_polygon = False if self.d_min_ctrl.GetValue() > 0: self.params.masking.d_min = self.d_min_ctrl.GetValue() else: self.params.masking.d_min = None if self.d_max_ctrl.GetValue() > 0: self.params.masking.d_max = self.d_max_ctrl.GetValue() else: self.params.masking.d_max = None self.params.masking.border = int(self.border_ctrl.GetValue()) if self.ice_rings_d_min_ctrl.GetValue() > 0: self.params.masking.ice_rings.d_min = self.ice_rings_d_min_ctrl.GetValue( ) else: self.params.masking.ice_rings.d_min = None if self.ice_rings_width_ctrl.GetValue() > 0: self.params.masking.ice_rings.width = self.ice_rings_width_ctrl.GetValue( ) self.params.masking.ice_rings.filter = self.ice_rings_ctrl.GetValue() self._resolution_range_d_min = float( self.resolution_range_d_min_ctrl.GetValue()) self._resolution_range_d_max = float( self.resolution_range_d_max_ctrl.GetValue()) if self._resolution_range_d_min > 0 and self._resolution_range_d_max > 0: self.params.masking.resolution_range.append( (self._resolution_range_d_min, self._resolution_range_d_max)) self._resolution_range_d_min = 0 self._resolution_range_d_max = 0 from dials.util import masking from libtbx.utils import flat_list untrusted_rectangle = self.untrusted_rectangle_ctrl.GetValue().strip() if len(untrusted_rectangle.strip()) > 0: rectangle = untrusted_rectangle.strip().replace(",", " ").split(" ") try: rectangle = [int(s) for s in rectangle] assert len(rectangle) == 4 panel = int(self.untrusted_rectangle_panel_ctrl.GetValue()) except Exception: pass else: untrusted = masking.phil_scope.extract().untrusted[0] untrusted.panel = panel untrusted.rectangle = rectangle self.params.masking.untrusted.append(untrusted) untrusted_polygon = self.untrusted_polygon_ctrl.GetValue().strip() if len(untrusted_polygon.strip()) > 0: polygon = untrusted_polygon.strip().replace(",", " ").split(" ") try: polygon = [int(s) for s in polygon] assert len(polygon) % 2 == 0 assert len(polygon) // 2 > 3 panel = int(self.untrusted_polygon_panel_ctrl.GetValue()) except Exception: pass else: untrusted = masking.phil_scope.extract().untrusted[0] untrusted.panel = panel untrusted.polygon = polygon self.params.masking.untrusted.append(untrusted) untrusted_circle = self.untrusted_circle_ctrl.GetValue().strip() if len(untrusted_circle.strip()) > 0: circle = untrusted_circle.strip().replace(",", " ").split(" ") try: circle = [int(s) for s in circle] assert len(circle) == 3 panel = int(self.untrusted_circle_panel_ctrl.GetValue()) except Exception: pass else: untrusted = masking.phil_scope.extract().untrusted[0] untrusted.panel = panel untrusted.circle = circle self.params.masking.untrusted.append(untrusted) # Refresh the UI *after* the event is finished wx.CallAfter(self.draw_settings) self.UpdateMask() # Force re-drawing of mask image_viewer_frame.OnChooseImage(event) def OnSaveMask(self, event): self.UpdateMask() image_viewer_frame = self.GetParent().GetParent() m1 = image_viewer_frame.mask_input m2 = image_viewer_frame.mask_image_viewer if m1 is not None and m2 is not None: mask = [] for p1, p2 in zip(m1, m2): mask.append(p2 & p1) elif m1 is not None: mask = m1 elif m2 is not None: mask = m2 else: return # Save the mask to file from libtbx import easy_pickle print("Writing mask to %s" % self.params.output.mask) easy_pickle.dump(self.params.output.mask, mask) def OnSaveMaskParams(self, event): from dials.util.masking import phil_scope params = phil_scope.extract() file_name = self.params.output.mask_params with open(file_name, "wb") as f: print("Saving parameters to %s" % file_name) phil_scope.fetch_diff(phil_scope.format( self.params.masking)).show(f) def UpdateMask(self): image_viewer_frame = self.GetParent().GetParent() # Generate the mask from dials.util.masking import MaskGenerator generator = MaskGenerator(self.params.masking) imageset = image_viewer_frame.imagesets[0] # XXX mask = generator.generate(imageset) image_viewer_frame.mask_image_viewer = mask image_viewer_frame.update_settings(layout=False) def OnLeftDown(self, event): if not event.ShiftDown(): click_posn = event.GetPositionTuple( ) if WX3 else event.GetPosition() if self._mode_rectangle: self._rectangle_x0y0 = click_posn self._rectangle_x1y1 = None return elif self._mode_circle: self._circle_xy = click_posn self._circle_radius = None return elif self._mode_polygon: self._mode_polygon_points.append(click_posn) self.DrawPolygon(self._mode_polygon_points) event.Skip() def OnLeftUp(self, event): if not event.ShiftDown(): click_posn = event.GetPositionTuple( ) if WX3 else event.GetPosition() if self._mode_rectangle and self._rectangle_x0y0 is not None: self._rectangle_x1y1 = click_posn x0, y0 = self._rectangle_x0y0 x1, y1 = self._rectangle_x1y1 self.AddUntrustedRectangle(x0, y0, x1, y1) self._pyslip.DeleteLayer(self._mode_rectangle_layer) self._mode_rectangle_layer = None self.mode_rectangle_button.SetValue(False) self.OnUpdate(event) return elif self._mode_circle and self._circle_xy is not None: xc, yc = self._circle_xy xedge, yedge = click_posn self.DrawCircle(xc, yc, xedge, yedge) try: self.AddUntrustedCircle(xc, yc, xedge, yedge) except Exception as e: print(e) finally: self._pyslip.DeleteLayer(self._mode_circle_layer) self._mode_circle_layer = None self.mode_circle_button.SetValue(False) self.OnUpdate(event) return event.Skip() def OnMove(self, event): if event.Dragging() and event.LeftIsDown() and not event.ShiftDown(): if self._mode_rectangle: if self._rectangle_x0y0 is not None: x0, y0 = self._rectangle_x0y0 x1, y1 = event.GetPositionTuple( ) if WX3 else event.GetPosition() self.DrawRectangle(x0, y0, x1, y1) return elif self._mode_circle: if self._circle_xy is not None: xc, yc = self._circle_xy xedge, yedge = (event.GetPositionTuple() if WX3 else event.GetPosition()) self.DrawCircle(xc, yc, xedge, yedge) return event.Skip() def DrawRectangle(self, x0, y0, x1, y1): if self._mode_rectangle_layer: self._pyslip.DeleteLayer(self._mode_rectangle_layer) self._mode_rectangle_layer = None polygon = [(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)] d = {} polygon_data = [] points = [self._pyslip.ConvertView2Geo(p) for p in polygon] for i in range(len(points) - 1): polygon_data.append(((points[i], points[i + 1]), d)) self._mode_rectangle_layer = self._pyslip.AddPolygonLayer( polygon_data, map_rel=True, color="#00ffff", radius=5, visible=True, name="<mode_rectangle_layer>", ) def DrawCircle(self, xc, yc, xedge, yedge): if self._mode_circle_layer: self._pyslip.DeleteLayer(self._mode_circle_layer) self._mode_circle_layer = None xc, yc = self._pyslip.ConvertView2Geo((xc, yc)) xedge, yedge = self._pyslip.ConvertView2Geo((xedge, yedge)) from scitbx import matrix center = matrix.col((xc, yc)) edge = matrix.col((xedge, yedge)) r = (center - edge).length() if r == 0: return e1 = matrix.col((1, 0)) e2 = matrix.col((0, 1)) circle_data = ( center + r * (e1 + e2), center + r * (e1 - e2), center + r * (-e1 - e2), center + r * (-e1 + e2), center + r * (e1 + e2), ) self._mode_circle_layer = self._pyslip.AddEllipseLayer( circle_data, map_rel=True, color="#00ffff", radius=5, visible=True, # show_levels=[3,4], name="<mode_circle_layer>", ) def DrawPolygon(self, vertices): if self._mode_polygon_layer: self._pyslip.DeleteLayer(self._mode_polygon_layer) self._mode_polygon_layer = None polygon_data = [] d = {} for i in range(len(vertices) - 1): polygon_data.append(( ( self._pyslip.ConvertView2Geo(vertices[i]), self._pyslip.ConvertView2Geo(vertices[i + 1]), ), d, )) if polygon_data: self._mode_polygon_layer = self._pyslip.AddPolygonLayer( polygon_data, map_rel=True, color="#00ffff", radius=5, visible=True, name="<boxsel_pt_layer>", ) def AddUntrustedPolygon(self, vertices): if len(vertices) < 4: return vertices.append(vertices[0]) vertices = [self._pyslip.ConvertView2Geo(v) for v in vertices] vertices = [ self._pyslip.tiles.map_relative_to_picture_fast_slow(*v) for v in vertices ] detector = self._pyslip.tiles.raw_image.get_detector() if len(detector) > 1: point_ = [] panel_id = None for p in vertices: p1, p0, p_id = self._pyslip.tiles.flex_image.picture_to_readout( p[1], p[0]) assert p_id >= 0, "Point must be within a panel" if panel_id is not None: assert ( panel_id == p_id ), "All points must be contained within a single panel" panel_id = p_id point_.append((p0, p1)) vertices = point_ else: panel_id = 0 from dials.util import masking from libtbx.utils import flat_list region = masking.phil_scope.extract().untrusted[0] points = flat_list(vertices) region.polygon = [int(p) for p in points] region.panel = panel_id self.params.masking.untrusted.append(region) def AddUntrustedRectangle(self, x0, y0, x1, y1): x0, y0 = self._pyslip.ConvertView2Geo((x0, y0)) x1, y1 = self._pyslip.ConvertView2Geo((x1, y1)) if x0 == x1 or y0 == y1: return points = [(x0, y0), (x1, y1)] points = [ self._pyslip.tiles.map_relative_to_picture_fast_slow(*p) for p in points ] detector = self._pyslip.tiles.raw_image.get_detector() if len(detector) > 1: point_ = [] panel_id = None for p in points: p1, p0, p_id = self._pyslip.tiles.flex_image.picture_to_readout( p[1], p[0]) assert p_id >= 0, "Point must be within a panel" if panel_id is not None: assert ( panel_id == p_id ), "All points must be contained within a single panel" panel_id = int(p_id) point_.append((p0, p1)) points = point_ else: panel_id = 0 (x0, y0), (x1, y1) = points if x0 > x1: x1, x0 = x0, x1 if y0 > y1: y1, y0 = y0, y1 panel = detector[panel_id] if (x1 < 0 or y1 < 0 or x0 > panel.get_image_size()[0] or y0 > panel.get_image_size()[1]): return x0 = max(0, x0) y0 = max(0, y0) x1 = min(panel.get_image_size()[0], x1) y1 = min(panel.get_image_size()[1], y1) from dials.util import masking from libtbx.utils import flat_list region = masking.phil_scope.extract().untrusted[0] region.rectangle = [int(x0), int(x1), int(y0), int(y1)] region.panel = panel_id self.params.masking.untrusted.append(region) def AddUntrustedCircle(self, xc, yc, xedge, yedge): points = [(xc, yc), (xedge, yedge)] points = [self._pyslip.ConvertView2Geo(p) for p in points] points = [ self._pyslip.tiles.map_relative_to_picture_fast_slow(*p) for p in points ] detector = self._pyslip.tiles.raw_image.get_detector() if len(detector) > 1: points_ = [] panel_id = None for p in points: p1, p0, p_id = self._pyslip.tiles.flex_image.picture_to_readout( p[1], p[0]) assert p_id >= 0, "Point must be within a panel" if panel_id is not None: assert ( panel_id == p_id ), "All points must be contained within a single panel" panel_id = p_id points_.append((p0, p1)) points = points_ else: panel_id = 0 (xc, yc), (xedge, yedge) = points from scitbx import matrix center = matrix.col((xc, yc)) edge = matrix.col((xedge, yedge)) r = (center - edge).length() if r == 0: return e1 = matrix.col((1, 0)) e2 = matrix.col((0, 1)) circle_data = ( center + r * (e1 + e2), center + r * (e1 - e2), center + r * (-e1 - e2), center + r * (-e1 + e2), center + r * (e1 + e2), ) from dials.util import masking from libtbx.utils import flat_list region = masking.phil_scope.extract().untrusted[0] region.circle = [int(xc), int(yc), int(r)] region.panel = panel_id self.params.masking.untrusted.append(region)
def __init__(self, parent, id, title, defaultFile, defaultPath, app): wx.Frame.__init__(self, parent, id, title, style=wx.CAPTION | wx.TAB_TRAVERSAL | wx.CLIP_CHILDREN) self.defaultFile = defaultFile # the filename of the default config file self.defaultPath = defaultPath # the initial path that is given for the file picker dialog self.app = app # reference to the application that constructed this frame # dimensions of main panel fullWidth = 300 buttonWidth = 100 borderWidth = 10 # create main panel mainPanel = wx.Panel(self, wx.ID_ANY) # create configuration widgets configBox = wx.StaticBox(mainPanel, wx.ID_ANY, label='Configuration file', style=wx.BORDER_SUNKEN) configBoxSizer = wx.StaticBoxSizer(configBox, wx.VERTICAL) self.configText = wx.TextCtrl(mainPanel, wx.ID_ANY, value=self.defaultFilename(), size=(fullWidth, -1), style=wx.TE_READONLY) self.createButton = wx.Button(mainPanel, wx.ID_ANY, label='Create...', size=(buttonWidth, -1)) self.loadButton = wx.Button(mainPanel, wx.ID_ANY, label='Load...', size=(buttonWidth, -1)) # layout configuration widgets configButtonSizer = wx.BoxSizer(wx.HORIZONTAL) configButtonSizer.Add(self.createButton, flag=wx.ALL, border=0) configButtonSizer.Add((fullWidth - 2 * buttonWidth, -1), 1) configButtonSizer.Add(self.loadButton, flag=wx.ALL, border=0) configBoxSizer.Add(self.configText, 0, wx.ALL, border=borderWidth) configBoxSizer.Add(configButtonSizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) configBoxSizer.Fit(configBox) # create visualization widgets visualBox = wx.StaticBox(mainPanel, wx.ID_ANY, label='Demonstration options', style=wx.BORDER_SUNKEN) visualBoxSizer = wx.StaticBoxSizer(visualBox, wx.VERTICAL) self.checkLevels = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Print A-weighted SPL at receivers to console') self.checkVehicles = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Print detailed vehicle information to console') self.checkTimeseries = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Send level timeseries at receivers to Viewer') # create slowdown spinbox self.slowdownTxt1 = wx.StaticText(mainPanel, -1, label=' Slowdown: ') self.slowdownSpin = FloatSpin(mainPanel, -1, size=(60, -1), digits=0, value=0, min_val=0, increment=50) self.slowdownSpin.GetTextCtrl().SetEditable(False) self.slowdownTxt2 = wx.StaticText(mainPanel, -1, label=' milliseconds/timestep') self.enableSlowdown(False) self.slowdownBoxSizer = wx.BoxSizer(wx.HORIZONTAL) self.slowdownBoxSizer.Add(self.slowdownTxt1, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.slowdownBoxSizer.Add(self.slowdownSpin, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.slowdownBoxSizer.Add(self.slowdownTxt2, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) # layout visualization widgets visualBoxSizer.Add(self.checkLevels, 0, wx.ALL, border=borderWidth) visualBoxSizer.Add(self.checkVehicles, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add(self.checkTimeseries, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add(self.slowdownBoxSizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add((fullWidth + 2 * borderWidth, -1), 1) visualBoxSizer.Fit(visualBox) # create buttons self.disableButton = wx.Button(mainPanel, wx.ID_ANY, label='Disable plugin', size=(buttonWidth, -1)) self.okButton = wx.Button(mainPanel, wx.ID_ANY, label='Ok', size=(buttonWidth, -1)) okButtonSizer = wx.BoxSizer(wx.HORIZONTAL) okButtonSizer.Add(self.disableButton, flag=wx.ALL, border=0) okButtonSizer.Add((fullWidth + 3 * borderWidth - 2 * buttonWidth, -1), 1) okButtonSizer.Add(self.okButton, flag=wx.ALL, border=0) # finally, add main sizer with border mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(configBoxSizer, 0, flag=wx.ALL, border=borderWidth) mainSizer.Add(visualBoxSizer, 0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) mainSizer.Add(okButtonSizer, 0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) mainPanel.SetSizerAndFit(mainSizer) self.Fit() # associate events with class methods self.createButton.Bind(wx.EVT_BUTTON, self.OnCreate) self.loadButton.Bind(wx.EVT_BUTTON, self.OnLoad) self.disableButton.Bind(wx.EVT_BUTTON, self.OnDisable) self.okButton.Bind(wx.EVT_BUTTON, self.OnOK) self.checkTimeseries.Bind(wx.EVT_CHECKBOX, self.OnTimeseries) self.okButton.SetFocus() # set result value to default self.checkFilename() self.app.result = None
def __init__(self, *args, **kwds): # XXX Support several rings. Plot radial distribution somewhere # (not here), but maybe distribution along ring. Drop-down menu # for ring center, and button to reset to beam center. super(RingSettingsPanel, self).__init__(*args, **kwds) # Needed to draw and delete the rings. XXX Applies to # calibration_frame as well? self._pyslip = self.GetParent().GetParent().pyslip sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) # Number of decimal digits for distances. self.digits = 2 # Distance control XXX probably does not belong here # print "DISTANCE",self.GetParent().GetParent().viewer._img # box = wx.BoxSizer(wx.HORIZONTAL) # from wxtbx.phil_controls.floatctrl import FloatCtrl # from wxtbx.phil_controls import EVT_PHIL_CONTROL # self.distance_ctrl = FloatCtrl(self, pos=(300,180), size=(80,-1), # value=80.00, # name="Detector Distance") # self.distance_ctrl.SetMax(1000) # self.distance_ctrl.SetMin(5) # self.distance_ctrl.SetOptional(False) # box.Add(self.distance_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # txtd = wx.StaticText(self, label="Detector Distance") # box.Add(txtd, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # s.Add(box) from wx.lib.agw.floatspin import EVT_FLOATSPIN, FloatSpin # XXX Should really make value be in Aangstroem resolution, and # have a non-linear slider. self._radius = 100 self._center = [0, 0] radius_max = 2000 radius_min = 10 # Radius controls. box = wx.BoxSizer(wx.HORIZONTAL) self.slider = wx.Slider( self, maxValue=radius_max, minValue=radius_min, size=(250, -1), style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL, value=self._radius, ) box.Add(self.slider, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_SLIDER, self.OnSlide, self.slider) self.spinner = FloatSpin( self, digits=self.digits, max_val=radius_max, min_val=radius_min, value=self._radius, ) box.Add(self.spinner, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.spinner) self.auto = wx.Button(self, label="Auto fit") self.Bind(wx.EVT_BUTTON, self.OnAutoFit, self.auto) box.Add(self.auto, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) sizer.Add(box) # Centering controls. box = wx.BoxSizer(wx.HORIZONTAL) self.spinner_fast = FloatSpin(self, digits=self.digits, name="fast_ctrl", value=self._center[0]) box.Add( self.spinner_fast, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center fast"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_fast) self.spinner_slow = FloatSpin(self, digits=self.digits, name="slow_ctrl", value=self._center[1]) box.Add( self.spinner_slow, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center slow"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_slow) sizer.Add(box) self.DrawRing()
def __init__(self, parent, global_store, ok_callback, port, *args, **kwargs): Dialog.__init__(self, parent, title='Port {0} tuning'.format(port.num)) self.global_store = global_store self.ok_callback = ok_callback self.port = port # Dialog. dialog_box = wx.BoxSizer(wx.VERTICAL) ## Self-calibration. calibration_static_box = wx.StaticBox(self, label='DAC self-calibration') calibration_box = wx.StaticBoxSizer(calibration_static_box, wx.VERTICAL) dialog_box.Add(calibration_box, flag=wx.EXPAND | wx.ALL, border=5) self.calibrate_button = wx.Button(self, label='Self-calibrate') self.Bind(wx.EVT_BUTTON, self.OnCalibrate, self.calibrate_button) calibration_box.Add(self.calibrate_button, flag=wx.EXPAND) ## Tuning. tuning_static_box = wx.StaticBox(self, label='Tuning') tuning_box = wx.StaticBoxSizer(tuning_static_box, wx.VERTICAL) dialog_box.Add(tuning_box, flag=wx.EXPAND) ### Autotune. autotuning_static_box = wx.StaticBox(self, label='Autotuning') autotuning_box = wx.StaticBoxSizer(autotuning_static_box, wx.VERTICAL) tuning_box.Add(autotuning_box, flag=wx.EXPAND | wx.ALL, border=5) autotuning_sizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5) autotuning_box.Add(autotuning_sizer, flag=wx.CENTER) autotuning_sizer.Add(wx.StaticText(self, label='Resource name:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.resource_name_input = wx.TextCtrl(self, size=(300, -1)) autotuning_sizer.Add(self.resource_name_input) autotuning_sizer.Add(wx.StaticText(self, label='Max:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.automax_input = FloatSpin(self, value=1, min_val=-10, max_val=10, increment=1, digits=5) autotuning_sizer.Add(self.automax_input) autotuning_sizer.Add(wx.StaticText(self, label='Min:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.automin_input = FloatSpin(self, value=-1, min_val=-10, max_val=10, increment=1, digits=5) autotuning_sizer.Add(self.automin_input) self.autotune_button = wx.Button(self, label='Autotune') self.Bind(wx.EVT_BUTTON, self.OnAutotune, self.autotune_button) autotuning_box.Add(self.autotune_button, flag=wx.EXPAND) ### Manual tune. tuning_sizer = wx.FlexGridSizer(rows=2, cols=2, hgap=5) tuning_box.Add(tuning_sizer, flag=wx.CENTER) tuning_sizer.Add(wx.StaticText(self, label='Gain:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.gain_input = FloatSpin(self, value=0, min_val=-1e6, max_val=1e6, increment=1, digits=5) tuning_sizer.Add(self.gain_input) tuning_sizer.Add(wx.StaticText(self, label='Offset:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.offset_input = FloatSpin(self, value=0, min_val=-1e6, max_val=1e6, increment=1, digits=5) tuning_sizer.Add(self.offset_input) ## End buttons. button_box = wx.BoxSizer(wx.HORIZONTAL) dialog_box.Add(button_box, flag=wx.CENTER | wx.ALL, border=5) ok_button = wx.Button(self, wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.OnOk, ok_button) button_box.Add(ok_button) cancel_button = wx.Button(self, wx.ID_CANCEL) button_box.Add(cancel_button) self.SetSizerAndFit(dialog_box)
def __init__(self, parent, global_store, vsrc, *args, **kwargs): wx.Panel.__init__(self, parent, *args, **kwargs) self.global_store = global_store self.vsrc = vsrc self.port_value_inputs = [] self.port_buttons = [] # Panel. panel_box = wx.BoxSizer(wx.VERTICAL) ## Ports. ports_box = wx.FlexGridSizer(rows=3, cols=2) panel_box.Add(ports_box) for port in range(4): port_static_box = wx.StaticBox(self, label='Port {0} '.format(port)) port_box = wx.StaticBoxSizer(port_static_box, wx.HORIZONTAL) ports_box.Add(port_box, flag=wx.ALL, border=5) spin = FloatSpin(self, value=0, min_val=-10, max_val=10, increment=1, digits=6) self.port_value_inputs.append(spin) port_box.Add(spin) port_box.Add(wx.StaticText(self, label='V')) set_button = wx.Button(self, label='Set', style=wx.BU_EXACTFIT) set_button.Bind(wx.EVT_BUTTON, partial(self.OnSetVoltage, port)) port_box.Add(set_button) tune_button = wx.Button(self, label='Tune...', style=wx.BU_EXACTFIT) tune_button.Bind(wx.EVT_BUTTON, partial(self.OnTune, port)) port_box.Add(tune_button) self.port_buttons.append((set_button, tune_button)) ## All ports. button_static_box = wx.StaticBox(self, label='All ports') button_box = wx.StaticBoxSizer(button_static_box, wx.HORIZONTAL) panel_box.Add(button_box, flag=wx.CENTER) ### Zero. zero_all_button = wx.Button(self, label='Zero') self.Bind(wx.EVT_BUTTON, self.OnZeroAll, zero_all_button) button_box.Add(zero_all_button, flag=wx.CENTER) ### Self-calibrate. self.calibrate_all_button = wx.Button(self, label='Self-calibrate') self.Bind(wx.EVT_BUTTON, self.OnCalibrateAll, self.calibrate_all_button) button_box.Add(self.calibrate_all_button, flag=wx.CENTER) ### Load tuning. tuning_data_static_box = wx.StaticBox(self, label='Tuning data') tuning_data_box = wx.StaticBoxSizer(tuning_data_static_box, wx.HORIZONTAL) button_box.Add(tuning_data_box) #### Save. tuning_data_save_button = wx.Button(self, label='Save...') self.Bind(wx.EVT_BUTTON, self.OnSave, tuning_data_save_button) tuning_data_box.Add(tuning_data_save_button) #### Load. tuning_data_load_button = wx.Button(self, label='Load...') self.Bind(wx.EVT_BUTTON, self.OnLoad, tuning_data_load_button) tuning_data_box.Add(tuning_data_load_button) self.SetSizer(panel_box)
def InitUi(self): panel = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) hbox1 = wx.BoxSizer(wx.HORIZONTAL) echelle_label = wx.StaticText(panel, -1, "Echelle : 1/") hbox1.Add(echelle_label, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,9) self.echelle = FloatSpin(panel, value=1 , min_val=1.0, increment=1.0, digits=8, size=(100,-1)) hbox1.Add(self.echelle, 2, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,4) vbox.Add(hbox1, 1, wx.EXPAND|wx.ALL, 1) #------------------------------------------- sb = wx.StaticBox(panel, label=" Perte de précision autorisé :") boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) self.perte_precision = wx.SpinCtrl(panel, value="1") self.perte_precision.SetRange(1, 8) self.perte_precision.SetValue(2) boxsizer.Add(self.perte_precision, 1, wx.ALL|wx.EXPAND, 1) #------------------------------------------- tmp = ["mm","cm","m","km"] self.rbox = wx.RadioBox(panel, label='', choices = tmp, majorDimension=1, style=wx.RA_SPECIFY_ROWS) boxsizer.Add(self.rbox, flag=wx.ALL|wx.ALIGN_CENTER, border=1) vbox.Add(boxsizer, 1, wx.EXPAND, 5) #------------------------------------------ hbox2 = wx.BoxSizer(wx.HORIZONTAL) partie_label = wx.StaticText(panel, -1, "Nombre de partie : ") hbox2.Add(partie_label, 0, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,9) self.nbre_partie = wx.TextCtrl(panel) self.nbre_partie.SetValue("") hbox2.Add(self.nbre_partie, 1, wx.EXPAND|wx.ALIGN_RIGHT|wx.ALL,4) vbox.Add(hbox2, 1, wx.EXPAND|wx.ALL, 1) #------------------------------------------- sb2 = wx.StaticBox(panel, label=" Clé de tatouage :") boxsizer = wx.StaticBoxSizer(sb2, wx.VERTICAL) self.cle = wx.TextCtrl(panel, size=(270,100), style=wx.TE_MULTILINE) self.cle.SetValue("") boxsizer.Add(self.cle, 22, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,4) vbox.Add(boxsizer, 1, wx.EXPAND|wx.ALL, 1) #---------------------------------------- sb3 = wx.StaticBox(panel, label=" Appliquer sur :") boxsizer = wx.StaticBoxSizer(sb3, wx.VERTICAL) tmp = ["Un morceau de la carte", "Carte Complète"] self.tatouer = wx.RadioBox(panel, label='', choices = tmp, majorDimension=1, style=wx.RA_SPECIFY_ROWS) boxsizer.Add(self.tatouer,flag=wx.RIGHT, border=5) vbox.Add(boxsizer, 1, wx.EXPAND|wx.ALL, 1) #----------------------------------------------- hbox4 = wx.BoxSizer(wx.HORIZONTAL) help_btn = wx.Button(panel,1, label='Help') ok_btn = wx.Button(panel, 2,label = "Ok") cancel_btn= wx.Button(panel,3, label="Cancel") self.Bind (wx.EVT_BUTTON, self.OnHelp, id=1) self.Bind (wx.EVT_BUTTON, self.OnOk, id=2) self.Bind (wx.EVT_BUTTON, self.OnCancel, id=3) hbox4.Add(help_btn, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 9) hbox4.Add(cancel_btn, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 9) hbox4.Add(ok_btn, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 9) vbox.Add(hbox4, 1, wx.EXPAND|wx.ALL, 1) panel.SetSizer(vbox)
def __init__(self, *args, **kwds): super().__init__(*args, **kwds) sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) # Number of decimal digits for distances. self.digits = 2 # Quad translation controls from wx.lib.agw.floatspin import EVT_FLOATSPIN, FloatSpin img = self.GetParent().GetParent().pyslip.tiles.raw_image d = img.get_detector() self._quad_spinners = [] for serial in range(4): fast, slow = d.hierarchy()[serial].get_origin()[0:2] name_quadrant = ["Q0", "Q1", "Q2", "Q3"][serial] box = wx.BoxSizer(wx.HORIZONTAL) for (name_direction, value) in [("fast", fast), ("slow", slow)]: name_ctrl = name_quadrant + "_" + name_direction + "_ctrl" spinner = FloatSpin(self, digits=self.digits, name=name_ctrl, value=value) self.Bind(EVT_FLOATSPIN, self.OnUpdateQuad, spinner) box.Add( spinner, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label=name_quadrant + " " + name_direction), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) setattr(self, "_" + name_ctrl, spinner) self._quad_spinners.append(spinner) sizer.Add(box) # Spinner amount control box = wx.BoxSizer(wx.HORIZONTAL) self._spinner_amt_control = FloatSpin( self, digits=self.digits, name="spin_amount", value=1, min_val=0.1, increment=0.1, ) self.Bind(EVT_FLOATSPIN, self.OnSpinAmount, self._spinner_amt_control) box.Add( self._spinner_amt_control, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Spinner increment (mm)"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) sizer.Add(box) box = wx.BoxSizer(wx.HORIZONTAL) btn = wx.Button(self, label="Restore metrology") box.Add(btn, flag=wx.ALL, border=5) self.Bind(wx.EVT_BUTTON, self.OnRestoreMetrology, btn) btn = wx.Button(self, label="Save current metrology") box.Add(btn, flag=wx.ALL, border=5) self.Bind(wx.EVT_BUTTON, self.OnSaveMetrology, btn) sizer.Add(box, flag=wx.ALIGN_CENTER)
class Reglage(wx.Dialog): """ Cette class pour la fenetre de réglage """ echelle, perte_precision, perte_precision_unite, nbre_partie, cle , tatouer= "", "", "", "", "", "" reglage_done = False def __init__(self, parent, title): super(Reglage, self).__init__(parent, title = "Réglages", size =(360,450), style =wx.CLOSE_BOX|wx.SYSTEM_MENU|wx.CAPTION | wx.CLOSE_BOX) self.InitUi() self.Center() def InitUi(self): panel = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) hbox1 = wx.BoxSizer(wx.HORIZONTAL) echelle_label = wx.StaticText(panel, -1, "Echelle : 1/") hbox1.Add(echelle_label, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,9) self.echelle = FloatSpin(panel, value=1 , min_val=1.0, increment=1.0, digits=8, size=(100,-1)) hbox1.Add(self.echelle, 2, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,4) vbox.Add(hbox1, 1, wx.EXPAND|wx.ALL, 1) #------------------------------------------- sb = wx.StaticBox(panel, label=" Perte de précision autorisé :") boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) self.perte_precision = wx.SpinCtrl(panel, value="1") self.perte_precision.SetRange(1, 8) self.perte_precision.SetValue(2) boxsizer.Add(self.perte_precision, 1, wx.ALL|wx.EXPAND, 1) #------------------------------------------- tmp = ["mm","cm","m","km"] self.rbox = wx.RadioBox(panel, label='', choices = tmp, majorDimension=1, style=wx.RA_SPECIFY_ROWS) boxsizer.Add(self.rbox, flag=wx.ALL|wx.ALIGN_CENTER, border=1) vbox.Add(boxsizer, 1, wx.EXPAND, 5) #------------------------------------------ hbox2 = wx.BoxSizer(wx.HORIZONTAL) partie_label = wx.StaticText(panel, -1, "Nombre de partie : ") hbox2.Add(partie_label, 0, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,9) self.nbre_partie = wx.TextCtrl(panel) self.nbre_partie.SetValue("") hbox2.Add(self.nbre_partie, 1, wx.EXPAND|wx.ALIGN_RIGHT|wx.ALL,4) vbox.Add(hbox2, 1, wx.EXPAND|wx.ALL, 1) #------------------------------------------- sb2 = wx.StaticBox(panel, label=" Clé de tatouage :") boxsizer = wx.StaticBoxSizer(sb2, wx.VERTICAL) self.cle = wx.TextCtrl(panel, size=(270,100), style=wx.TE_MULTILINE) self.cle.SetValue("") boxsizer.Add(self.cle, 22, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,4) vbox.Add(boxsizer, 1, wx.EXPAND|wx.ALL, 1) #---------------------------------------- sb3 = wx.StaticBox(panel, label=" Appliquer sur :") boxsizer = wx.StaticBoxSizer(sb3, wx.VERTICAL) tmp = ["Un morceau de la carte", "Carte Complète"] self.tatouer = wx.RadioBox(panel, label='', choices = tmp, majorDimension=1, style=wx.RA_SPECIFY_ROWS) boxsizer.Add(self.tatouer,flag=wx.RIGHT, border=5) vbox.Add(boxsizer, 1, wx.EXPAND|wx.ALL, 1) #----------------------------------------------- hbox4 = wx.BoxSizer(wx.HORIZONTAL) help_btn = wx.Button(panel,1, label='Help') ok_btn = wx.Button(panel, 2,label = "Ok") cancel_btn= wx.Button(panel,3, label="Cancel") self.Bind (wx.EVT_BUTTON, self.OnHelp, id=1) self.Bind (wx.EVT_BUTTON, self.OnOk, id=2) self.Bind (wx.EVT_BUTTON, self.OnCancel, id=3) hbox4.Add(help_btn, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 9) hbox4.Add(cancel_btn, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 9) hbox4.Add(ok_btn, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 9) vbox.Add(hbox4, 1, wx.EXPAND|wx.ALL, 1) panel.SetSizer(vbox) def OnOk(self, event): if not __champ_valide__(self.nbre_partie.GetValue()): dial = wx.MessageDialog(None,"Nombre de parties doit etre un Entier positif", 'Error',wx.ICON_ERROR) ret = dial.ShowModal() if ret == wx.ID_YES: self.Destroy() return if self.cle.GetValue() == "": dial = wx.MessageDialog(None, "Valeur de Cle abscente ", 'Error',wx.ICON_ERROR) ret = dial.ShowModal() if ret == wx.ID_YES: self.Destroy() return self.GetParent().leftpanel.echelle_label.SetLabelText(" Echelle = 1/"+str(self.echelle.GetValue())) self.GetParent().leftpanel.perte_precision_label.SetLabelText(" Delta = "+str(self.perte_precision.GetValue())) self.GetParent().leftpanel.nbre_partie_label.SetLabelText(" Nombre de parties = "+str(self.nbre_partie.GetValue())) self.GetParent().leftpanel.cle_label.SetValue(str(self.cle.GetValue())) self.GetParent().leftpanel.cle_label.SetEditable(False) self.GetParent().leftpanel.lancer_tatouage_btn.Enable() self.GetParent().leftpanel.lancer_detection_btn.Enable() # ici, ca dépent il veut vérifier si la carte est tatoué ou non sans faire passé par un tatouage Reglage.echelle = self.echelle.GetValue() Reglage.perte_precision = self.perte_precision.GetValue() Reglage.perte_precision_unite = self.rbox.GetStringSelection() Reglage.nbre_partie = self.nbre_partie.GetValue() Reglage.cle = self.cle.GetValue() Reglage.tatouer = self.tatouer.GetStringSelection() Reglage.reglage_done = True self.Close() def OnHelp(self, event): try : import webbrowser webbrowser.open_new_tab('aide.html') except : pass def OnCancel(self, event): self.Close()
def addItem(self, item): colors = [ "blue", "black", "green", "red", "yellow", "orange", "pink", "purple", "brown", "gray", "darkblue", "silver", "darkgreen", "darkred", "gold" ] styles = ["-", "-.", ":", "steps", "--", "_"] #create elements i = self.list.GetItemCount() index = self.list.InsertStringItem(i, item.filename) box = wx.CheckBox(self.list) box.SetValue(True) dx = FloatSpin(self.list, -1, value=-item.surface, min_val=-500.000, max_val=500.000, increment=1, digits=2) dy = FloatSpin(self.list, -1, value=0.000, min_val=-50.00, max_val=50.00, increment=0.01, digits=2) stretch = FloatSpin(self.list, -1, value=1, min_val=0.5, max_val=1.5, increment=0.001, digits=3) smooth = wx.SpinCtrl(self.list, -1, min=0, max=2000, initial=200) color = wx.ComboBox(self.list, -1, choices=colors, style=wx.CB_READONLY, value=colors[i % len(colors)]) style = wx.ComboBox(self.list, -1, choices=styles, style=wx.CB_READONLY, value="-") width = wx.SpinCtrl(self.list, -1, name="Width", initial=1, min=1, max=10) #append elements to files properties item.index = index item.box = box item.dx = dx item.dy = dy item.stretch = stretch item.smooth = smooth item.color = color item.style = style item.width = width #append elements to list self.list.SetItemWindow(index, 1, item.box, expand=True) self.list.SetItemWindow(index, 2, item.dx, expand=True) self.list.SetItemWindow(index, 3, item.dy, expand=True) self.list.SetItemWindow(index, 4, item.stretch, expand=True) self.list.SetItemWindow(index, 5, item.smooth, expand=True) self.list.SetItemWindow(index, 6, item.color, expand=True) self.list.SetItemWindow(index, 7, item.style, expand=True) self.list.SetItemWindow(index, 8, item.width, expand=True) #set events to update plot self.Bind(wx.EVT_CHECKBOX, self.OnUpdatePlot, item.box) self.Bind(wx.EVT_SPINCTRL, self.OnUpdatePlot, item.dx) self.Bind(wx.EVT_SPINCTRL, self.OnUpdatePlot, item.dy) self.Bind(wx.EVT_SPINCTRL, self.OnUpdatePlot, item.stretch) self.Bind(wx.EVT_SPINCTRL, self.OnUpdatePlot, item.smooth) self.Bind(wx.EVT_COMBOBOX, self.OnUpdatePlot, item.color) self.Bind(wx.EVT_COMBOBOX, self.OnUpdatePlot, item.style) self.Bind(wx.EVT_SPINCTRL, self.OnUpdatePlot, item.width)
def __init__(self, parent=None, extended=True): """Constructor""" wx.Dialog.__init__( self, parent, wx.ID_ANY, "Graph Options", size=(600, 450), ) self.parent = parent colors = [ "blue", "black", "green", "red", "yellow", "orange", "pink", "purple", "brown", "gray", "darkblue", "silver", "darkgreen", "darkred", "gold" ] styles = ["-", "-.", ":", "steps", "--", "_"] #axis self.xlabel = "Depth [mm]" self.ylabel = "Force [N]" self.xlim = (0, 300) self.auto_x = True self.ylim = (-1, 41) self.auto_y = True self.xticks = 10 self.auto_xticks = True self.yticks = 10 self.auto_yticks = True self.mirrorx = False self.mirrory = False self.plot_title = "SMP Measurement" self.logscale = False #data self.color = colors[0] self.style = styles[0] self.width = 1 self.sampling = 10 #gradient self.grad_color = colors[3] self.grad_style = styles[2] self.grad_width = 1 self.grad_sampling = 1000 #median self.median_color = colors[9] self.median_style = styles[0] self.median_width = 1 self.median_sampling = 200 panel = wx.Panel(self) notebook = Tabs(panel, extended) confirm = wx.Button(panel, wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.onOK, confirm) cancel = wx.Button(panel, wx.ID_CANCEL) self.Bind(wx.EVT_BUTTON, self.onCancel, cancel) apply = wx.Button(panel, wx.ID_APPLY) self.Bind(wx.EVT_BUTTON, self.onApply, apply) vsizer = wx.BoxSizer(wx.VERTICAL) vsizer.Add(notebook, 1, wx.ALL | wx.EXPAND) hsizer = wx.BoxSizer(wx.HORIZONTAL) hsizer.Add(cancel) hsizer.Add(apply) hsizer.Add(confirm) vsizer.Add(hsizer, 0, wx.ALIGN_RIGHT) panel.SetSizer(vsizer) self.Layout() #axis self.box_autox = wx.CheckBox(notebook.tabAxis, -1, 'Auto X') self.Bind(wx.EVT_CHECKBOX, self.onUpdate, self.box_autox) self.box_autoy = wx.CheckBox(notebook.tabAxis, -1, 'Auto Y') self.Bind(wx.EVT_CHECKBOX, self.onUpdate, self.box_autoy) self.box_autox_tick = wx.CheckBox(notebook.tabAxis, -1, 'Auto X ticks') self.Bind(wx.EVT_CHECKBOX, self.onUpdate, self.box_autox_tick) self.box_autoy_tick = wx.CheckBox(notebook.tabAxis, -1, 'Auto Y ticks') self.Bind(wx.EVT_CHECKBOX, self.onUpdate, self.box_autoy_tick) self.box_mirrorx = wx.CheckBox(notebook.tabAxis, -1, 'Mirror X') self.box_mirrory = wx.CheckBox(notebook.tabAxis, -1, 'Mirror Y') self.xmin = FloatSpin(notebook.tabAxis, -1, value=self.xlim[0], min_val=-100.00, max_val=1800.00, increment=1, digits=3) label_xmin = wx.StaticText(notebook.tabAxis, -1, 'X min') self.ymin = FloatSpin(notebook.tabAxis, -1, value=self.ylim[0], min_val=-100.00, max_val=1800.00, increment=1, digits=3) label_ymin = wx.StaticText(notebook.tabAxis, -1, 'Y min') self.xmax = FloatSpin(notebook.tabAxis, -1, value=self.xlim[1], min_val=-100.00, max_val=1800.00, increment=1, digits=3) label_xmax = wx.StaticText(notebook.tabAxis, -1, 'X max') self.ymax = FloatSpin(notebook.tabAxis, -1, value=self.ylim[1], min_val=-100.00, max_val=1800.00, increment=1, digits=3) label_ymax = wx.StaticText(notebook.tabAxis, -1, 'Y max') self.xlabel_ctrl = wx.TextCtrl(notebook.tabAxis, -1, size=(200, -1), value=self.xlabel) label_xlabel = wx.StaticText(notebook.tabAxis, -1, 'X label') self.ylabel_ctrl = wx.TextCtrl(notebook.tabAxis, -1, size=(200, -1), value=self.ylabel) label_ylabel = wx.StaticText(notebook.tabAxis, -1, 'Y label') label_xticks = wx.StaticText(notebook.tabAxis, -1, 'X ticks') self.xticks_ctrl = wx.SpinCtrl(notebook.tabAxis, -1, size=(100, -1), min=1, max=100, initial=self.xticks, name="X ticks") label_yticks = wx.StaticText(notebook.tabAxis, -1, 'Y ticks') self.yticks_ctrl = wx.SpinCtrl(notebook.tabAxis, -1, size=(100, -1), min=1, max=100, initial=self.yticks, name="Y ticks") self.scale_ctrl = wx.CheckBox(notebook.tabAxis, -1, "Log Scale") self.box_autox.SetValue(True) self.xmin.Enable(False) self.xmax.Enable(False) self.box_autoy.SetValue(True) self.ymin.Enable(False) self.ymax.Enable(False) self.xticks_ctrl.Enable(False) self.yticks_ctrl.Enable(False) self.box_autox_tick.SetValue(True) self.box_autoy_tick.SetValue(True) self.box_mirrorx.SetValue(self.mirrorx) self.box_mirrory.SetValue(self.mirrory) self.scale_ctrl.SetValue(self.logscale) font = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD, True) #graph label_data = wx.StaticText(notebook.tabGraph, -1, "Data Plot") label_sampling = wx.StaticText(notebook.tabGraph, -1, 'Down sampling Factor') self.sampling_ctrl = wx.SpinCtrl(notebook.tabGraph, -1, size=(100, -1), min=0, max=1000, initial=self.sampling, name="Sampling") label_color = wx.StaticText(notebook.tabGraph, -1, 'Line Color') self.color_ctrl = wx.ComboBox(notebook.tabGraph, -1, size=(150, -1), choices=colors, style=wx.CB_READONLY, value=self.color) label_style = wx.StaticText(notebook.tabGraph, -1, 'Line Style') self.style_ctrl = wx.ComboBox(notebook.tabGraph, -1, size=(150, -1), choices=styles, style=wx.CB_READONLY, value=self.style) label_width = wx.StaticText(notebook.tabGraph, -1, 'Line Width') self.width_ctrl = wx.SpinCtrl(notebook.tabGraph, -1, name="Width", initial=1, min=0.5, max=10, pos=(325, 135), size=(50, -1)) #gradient label_grad = wx.StaticText(notebook.tabGraph, -1, "Gradient") label_grad_sampling = wx.StaticText(notebook.tabGraph, -1, 'Down sampling Factor') self.grad_sampling_ctrl = wx.SpinCtrl(notebook.tabGraph, -1, size=(100, -1), min=0, max=1000, initial=self.grad_sampling, name="Sampling") label_grad_color = wx.StaticText(notebook.tabGraph, -1, 'Line Color') self.grad_color_ctrl = wx.ComboBox(notebook.tabGraph, -1, size=(150, -1), choices=colors, style=wx.CB_READONLY, value=self.grad_color) label_grad_style = wx.StaticText(notebook.tabGraph, -1, 'Line Style') self.grad_style_ctrl = wx.ComboBox(notebook.tabGraph, -1, size=(150, -1), choices=styles, style=wx.CB_READONLY, value=self.grad_style) label_grad_width = wx.StaticText(notebook.tabGraph, -1, 'Line Width') self.grad_width_ctrl = wx.SpinCtrl(notebook.tabGraph, -1, name="Width", initial=1, min=0.5, max=10, pos=(325, 135), size=(50, -1)) #median label_median = wx.StaticText(notebook.tabGraph, -1, "Median") label_median_sampling = wx.StaticText(notebook.tabGraph, -1, 'Window') self.median_sampling_ctrl = wx.SpinCtrl(notebook.tabGraph, -1, size=(100, -1), min=0, max=1000, initial=self.median_sampling, name="Sampling") label_median_color = wx.StaticText(notebook.tabGraph, -1, 'Line Color') self.median_color_ctrl = wx.ComboBox(notebook.tabGraph, -1, size=(150, -1), choices=colors, style=wx.CB_READONLY, value=self.median_color) label_median_style = wx.StaticText(notebook.tabGraph, -1, 'Line Style') self.median_style_ctrl = wx.ComboBox(notebook.tabGraph, -1, size=(150, -1), choices=styles, style=wx.CB_READONLY, value=self.median_style) label_median_width = wx.StaticText(notebook.tabGraph, -1, 'Line Width') self.median_width_ctrl = wx.SpinCtrl(notebook.tabGraph, -1, name="Width", initial=1, min=0.5, max=10, pos=(325, 135), size=(50, -1)) vert1 = wx.BoxSizer(wx.VERTICAL) vert2 = wx.BoxSizer(wx.VERTICAL) hor1 = wx.BoxSizer(wx.HORIZONTAL) hor1.Add(self.box_autoy, 0, wx.ALIGN_CENTER | wx.ALL) hor1.Add(self.scale_ctrl, 0, wx.ALIGN_CENTER | wx.ALL) vert1.Add(self.box_autox, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(hor1, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(label_xmin, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.xmin, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_ymin, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.ymin, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(label_xmax, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.xmax, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_ymax, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.ymax, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(label_xlabel, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.xlabel_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_ylabel, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.ylabel_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(self.box_autox_tick, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(label_xticks, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.xticks_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(self.box_mirrorx, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(self.box_autoy_tick, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_yticks, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.yticks_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(self.box_mirrory, 0, wx.ALIGN_CENTER | wx.ALL, 10) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(vert1, wx.ALIGN_CENTER) sizer.Add( wx.StaticLine(notebook.tabAxis, style=wx.LI_VERTICAL, size=(-1, 600))) sizer.Add(vert2, wx.ALIGN_CENTER) notebook.tabAxis.SetSizer(sizer) vert1 = wx.BoxSizer(wx.VERTICAL) vert2 = wx.BoxSizer(wx.VERTICAL) vert3 = wx.BoxSizer(wx.VERTICAL) vert1.Add(label_data, 0, wx.ALIGN_CENTER | wx.ALL, 20) vert1.Add(label_sampling, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.sampling_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(label_color, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.color_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(label_width, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.width_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert1.Add(label_style, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert1.Add(self.style_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_grad, 0, wx.ALIGN_CENTER | wx.ALL, 20) vert2.Add(label_grad_sampling, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.grad_sampling_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_grad_color, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.grad_color_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_grad_width, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.grad_width_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert2.Add(label_grad_style, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert2.Add(self.grad_style_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert3.Add(label_median, 0, wx.ALIGN_CENTER | wx.ALL, 20) vert3.Add(label_median_sampling, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert3.Add(self.median_sampling_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert3.Add(label_median_color, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert3.Add(self.median_color_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert3.Add(label_median_width, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert3.Add(self.median_width_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) vert3.Add(label_median_style, 0, wx.ALIGN_CENTER | wx.RIGHT, 10) vert3.Add(self.median_style_ctrl, 0, wx.ALIGN_CENTER | wx.ALL, 10) label_data.SetFont(font) label_grad.SetFont(font) label_median.SetFont(font) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(vert1, wx.ALIGN_CENTER | wx.ALIGN_BOTTOM) sizer.Add( wx.StaticLine(notebook.tabGraph, style=wx.LI_VERTICAL, size=(-1, 600))) sizer.Add(vert2, wx.ALIGN_CENTER | wx.ALIGN_BOTTOM) sizer.Add( wx.StaticLine(notebook.tabGraph, style=wx.LI_VERTICAL, size=(-1, 600))) sizer.Add(vert3, wx.ALIGN_CENTER | wx.ALIGN_BOTTOM) notebook.tabGraph.SetSizer(sizer)
def __init__(self, *args, **kwds): super(UCSettingsPanel, self).__init__(*args, **kwds) self.phil_params = args[0].phil_params # Needed to draw and delete the rings. XXX Applies to # calibration_frame as well? self._pyslip = self.GetParent().GetParent().pyslip sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) # Number of decimal digits for distances. self.digits = 2 # Wavelength control. beam = self._pyslip.tiles.raw_image.get_beam() self._wavelength = beam.get_wavelength() # Unit cell controls. if self.phil_params.calibrate_unit_cell.unit_cell is not None: self._cell = list( self.phil_params.calibrate_unit_cell.unit_cell.parameters()) else: self._cell = [4.18, 4.72, 58.38, 89.44, 89.63, 75.85] if self.phil_params.calibrate_unit_cell.space_group is not None: self._spacegroup = self.phil_params.calibrate_unit_cell.space_group else: self._spacegroup = "P1" self._show_hkl = self.phil_params.calibrate_unit_cell.show_hkl self._cell_control_names = [ "uc_a_ctrl", "uc_b_ctrl", "uc_c_ctrl", "uc_alpha_ctrl", "uc_beta_ctrl", "uc_gamma_ctrl", ] box = wx.BoxSizer(wx.HORIZONTAL) self.uc_a = FloatSpin( self, digits=self.digits, name=self._cell_control_names[0], value=self._cell[0], ) box.Add(self.uc_a, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="a"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_a) self.uc_alpha = FloatSpin( self, digits=self.digits, name=self._cell_control_names[3], value=self._cell[3], ) box.Add( self.uc_alpha, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add(wx.StaticText(self, label="alpha"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_alpha) sizer.Add(box) box = wx.BoxSizer(wx.HORIZONTAL) self.uc_b = FloatSpin( self, digits=self.digits, name=self._cell_control_names[1], value=self._cell[1], ) box.Add(self.uc_b, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="b"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_b) self.uc_beta = FloatSpin( self, digits=self.digits, name=self._cell_control_names[4], value=self._cell[4], ) box.Add(self.uc_beta, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="beta"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_beta) sizer.Add(box) box = wx.BoxSizer(wx.HORIZONTAL) self.uc_c = FloatSpin( self, digits=self.digits, name=self._cell_control_names[2], value=self._cell[2], ) box.Add(self.uc_c, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(wx.StaticText(self, label="c"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_c) self.uc_gamma = FloatSpin( self, digits=self.digits, name=self._cell_control_names[5], value=self._cell[5], ) box.Add( self.uc_gamma, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add(wx.StaticText(self, label="gamma"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCell, self.uc_gamma) sizer.Add(box) # Space group control box = wx.BoxSizer(wx.HORIZONTAL) self.space_group_ctrl = wx.TextCtrl(self, name="space group", value=self._spacegroup) box.Add( self.space_group_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Space group"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(wx.EVT_TEXT, self.OnSpaceGroup, self.space_group_ctrl) sizer.Add(box) # Distance control img = self.GetParent().GetParent()._img box = wx.BoxSizer(wx.HORIZONTAL) self.distance_ctrl = FloatSpin( self, digits=self.digits, name="Detector Distance", value=img.get_detector_distance(), ) self.distance_ctrl.SetIncrement(0.5) box.Add( self.distance_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) txtd = wx.StaticText(self, label="Detector Distance") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.distance_ctrl) sizer.Add(box) # Wavelength control img = self.GetParent().GetParent()._img box = wx.BoxSizer(wx.HORIZONTAL) self.wavelength_ctrl = FloatSpin(self, digits=4, name="Wavelength", value=img.get_wavelength()) self.wavelength_ctrl.SetIncrement(0.05) box.Add( self.wavelength_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) txtw = wx.StaticText(self, label="Wavelength") box.Add(txtw, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.wavelength_ctrl) sizer.Add(box) # d_min control if self.phil_params.calibrate_unit_cell.d_min is not None: self.d_min = self.phil_params.calibrate_unit_cell.d_min else: self.d_min = 3.5 box = wx.BoxSizer(wx.HORIZONTAL) self.d_min_ctrl = FloatSpin(self, digits=self.digits, name="d_min", value=self.d_min) box.Add( self.d_min_ctrl, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) txtd = wx.StaticText(self, label="Highest resolution for ring display") box.Add(txtd, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.d_min_ctrl) sizer.Add(box) # Centering controls. self._center = [0, 0] box = wx.BoxSizer(wx.HORIZONTAL) self.spinner_fast = FloatSpin(self, digits=self.digits, name="fast_ctrl", value=self._center[0]) box.Add( self.spinner_fast, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center fast"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_fast) self.spinner_slow = FloatSpin(self, digits=self.digits, name="slow_ctrl", value=self._center[1]) box.Add( self.spinner_slow, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center slow"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) origin_box = wx.BoxSizer(wx.HORIZONTAL) self.origin = wx.StaticText(self, label="") origin_box.Add(self.origin, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_slow) sizer.Add(box) sizer.Add(origin_box) self.DrawRings()
class ExampleSettingsPanel(wx.Panel): def __init__(self, *args, **kwds): super(ExampleSettingsPanel, self).__init__(*args, **kwds) # Needed to draw and delete the overlay self._pyslip = self.GetParent().GetParent().pyslip sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) # Number of decimal digits self.digits = 2 from wx.lib.agw.floatspin import EVT_FLOATSPIN, FloatSpin # Set initial values self._radius = 100 self._center = [0, 0] radius_max = 2000 radius_min = 10 # Bind data to controls -- duplicate this section for each control box = wx.BoxSizer(wx.HORIZONTAL) self.slider = wx.Slider(self, maxValue=radius_max, minValue=radius_min, size=(250, -1), style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL, value=self._radius) box.Add(self.slider, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_SLIDER, self.OnSlide, self.slider) self.spinner = FloatSpin(self, digits=self.digits, max_val=radius_max, min_val=radius_min, value=self._radius) box.Add(self.spinner, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.spinner) sizer.Add(box) # end duplicate section # Update self.DrawRing() def __del__(self): # Delete layer method if (hasattr(self, "_ring_layer") and self._ring_layer is not None): self._pyslip.DeleteLayer(self._ring_layer) def OnSlide(self, event): # Keep slider and spinner synchronized obj = event.EventObject self._radius = obj.GetValue() self.spinner.SetValue(self._radius) self.DrawRing() def OnSpin(self, event): # Keep slider and spinner synchronized obj = event.EventObject self._radius = obj.GetValue() self.slider.SetValue(self._radius) self.DrawRing() def _draw_ring_layer(self, dc, data, map_rel): """Draw a points layer. dc the device context to draw on data an iterable of point tuples: (x, y, place, radius, colour, x_off, y_off, pdata) map_rel points relative to map if True, MUST BE TRUE for lightweight Assumes all points are the same colour, saving 100's of ms. """ assert map_rel is True if len(data) == 0: return (lon, lat, place, radius, colour, x_off, y_off, pdata) = data[0] scale = 2**self._pyslip.tiles.zoom_level # Draw points on map/view, using transparency if implemented. try: dc = wx.GCDC(dc) except NotImplementedError: pass dc.SetPen(wx.Pen(colour)) dc.SetBrush(wx.Brush(colour, wx.TRANSPARENT)) for (lon, lat, place, radius, colour, x_off, y_off, pdata) in data: (x, y) = self._pyslip.ConvertGeo2View((lon, lat)) dc.DrawCircle(x, y, radius * scale) def DrawRing(self): detector = self._pyslip.tiles.raw_image.get_detector() beam = self._pyslip.tiles.raw_image.get_beam() if len(detector) > 1: beam_pixel_fast, beam_pixel_slow = detector[ 0].millimeter_to_pixel( # FIXME assumes all detector elements use the same detector.hierarchy().get_beam_centre( beam.get_s0())) # millimeter-to-pixel convention else: beam_pixel_fast, beam_pixel_slow = detector[0].millimeter_to_pixel( detector[0].get_beam_centre(beam.get_s0())) center = self._pyslip.tiles.picture_fast_slow_to_map_relative( beam_pixel_fast + self._center[0], beam_pixel_slow + self._center[1]) ring_data = [(center[0], center[1], { "colour": "red", "radius": self._radius })] # Remove the old ring layer, and draw a new one. if (hasattr(self, "_ring_layer") and self._ring_layer is not None): self._pyslip.DeleteLayer(self._ring_layer) self._ring_layer = None self._ring_layer = self._pyslip.AddPointLayer( ring_data, map_rel=True, visible=True, show_levels=[-3, -2, -1, 0, 1, 2, 3, 4, 5], renderer=self._draw_ring_layer, name="<ring_layer>")
class ConfigFrame(wx.Frame): """ configuration window class, shown at the start of the simulation, for picking the configuration file and setting visualization flags """ def __init__(self, parent, id, title, defaultFile, defaultPath, app): wx.Frame.__init__(self, parent, id, title, style=wx.CAPTION | wx.TAB_TRAVERSAL | wx.CLIP_CHILDREN) self.defaultFile = defaultFile # the filename of the default config file self.defaultPath = defaultPath # the initial path that is given for the file picker dialog self.app = app # reference to the application that constructed this frame # dimensions of main panel fullWidth = 300 buttonWidth = 100 borderWidth = 10 # create main panel mainPanel = wx.Panel(self, wx.ID_ANY) # create configuration widgets configBox = wx.StaticBox(mainPanel, wx.ID_ANY, label='Configuration file', style=wx.BORDER_SUNKEN) configBoxSizer = wx.StaticBoxSizer(configBox, wx.VERTICAL) self.configText = wx.TextCtrl(mainPanel, wx.ID_ANY, value=self.defaultFilename(), size=(fullWidth, -1), style=wx.TE_READONLY) self.createButton = wx.Button(mainPanel, wx.ID_ANY, label='Create...', size=(buttonWidth, -1)) self.loadButton = wx.Button(mainPanel, wx.ID_ANY, label='Load...', size=(buttonWidth, -1)) # layout configuration widgets configButtonSizer = wx.BoxSizer(wx.HORIZONTAL) configButtonSizer.Add(self.createButton, flag=wx.ALL, border=0) configButtonSizer.Add((fullWidth - 2 * buttonWidth, -1), 1) configButtonSizer.Add(self.loadButton, flag=wx.ALL, border=0) configBoxSizer.Add(self.configText, 0, wx.ALL, border=borderWidth) configBoxSizer.Add(configButtonSizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) configBoxSizer.Fit(configBox) # create visualization widgets visualBox = wx.StaticBox(mainPanel, wx.ID_ANY, label='Demonstration options', style=wx.BORDER_SUNKEN) visualBoxSizer = wx.StaticBoxSizer(visualBox, wx.VERTICAL) self.checkLevels = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Print A-weighted SPL at receivers to console') self.checkVehicles = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Print detailed vehicle information to console') self.checkTimeseries = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Send level timeseries at receivers to Viewer') # create slowdown spinbox self.slowdownTxt1 = wx.StaticText(mainPanel, -1, label=' Slowdown: ') self.slowdownSpin = FloatSpin(mainPanel, -1, size=(60, -1), digits=0, value=0, min_val=0, increment=50) self.slowdownSpin.GetTextCtrl().SetEditable(False) self.slowdownTxt2 = wx.StaticText(mainPanel, -1, label=' milliseconds/timestep') self.enableSlowdown(False) self.slowdownBoxSizer = wx.BoxSizer(wx.HORIZONTAL) self.slowdownBoxSizer.Add(self.slowdownTxt1, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.slowdownBoxSizer.Add(self.slowdownSpin, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.slowdownBoxSizer.Add(self.slowdownTxt2, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) # layout visualization widgets visualBoxSizer.Add(self.checkLevels, 0, wx.ALL, border=borderWidth) visualBoxSizer.Add(self.checkVehicles, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add(self.checkTimeseries, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add(self.slowdownBoxSizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add((fullWidth + 2 * borderWidth, -1), 1) visualBoxSizer.Fit(visualBox) # create buttons self.disableButton = wx.Button(mainPanel, wx.ID_ANY, label='Disable plugin', size=(buttonWidth, -1)) self.okButton = wx.Button(mainPanel, wx.ID_ANY, label='Ok', size=(buttonWidth, -1)) okButtonSizer = wx.BoxSizer(wx.HORIZONTAL) okButtonSizer.Add(self.disableButton, flag=wx.ALL, border=0) okButtonSizer.Add((fullWidth + 3 * borderWidth - 2 * buttonWidth, -1), 1) okButtonSizer.Add(self.okButton, flag=wx.ALL, border=0) # finally, add main sizer with border mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(configBoxSizer, 0, flag=wx.ALL, border=borderWidth) mainSizer.Add(visualBoxSizer, 0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) mainSizer.Add(okButtonSizer, 0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) mainPanel.SetSizerAndFit(mainSizer) self.Fit() # associate events with class methods self.createButton.Bind(wx.EVT_BUTTON, self.OnCreate) self.loadButton.Bind(wx.EVT_BUTTON, self.OnLoad) self.disableButton.Bind(wx.EVT_BUTTON, self.OnDisable) self.okButton.Bind(wx.EVT_BUTTON, self.OnOK) self.checkTimeseries.Bind(wx.EVT_CHECKBOX, self.OnTimeseries) self.okButton.SetFocus() # set result value to default self.checkFilename() self.app.result = None def defaultFilename(self): """ return the default filename, including the full path """ return os.path.join(self.defaultPath, self.defaultFile) def checkFilename(self): """ check if the filename in the configText exists, and apply the necessary gui updates """ # fetch the full filename filename = self.configText.GetValue() if os.path.exists(filename): # enable OK button self.okButton.Enable(True) return True else: # clear the filename box self.configText.SetValue('') # disable the OK button self.okButton.Enable(False) return False def enableSlowdown(self, flag=True): """ enable or disable the slowdown spinbox """ for widget in [ self.slowdownTxt1, self.slowdownSpin, self.slowdownTxt2 ]: widget.Enable(flag) def OnTimeseries(self, event): """ executed when the user toggles the checkTimeseries check box """ self.enableSlowdown(self.checkTimeseries.GetValue()) def OnCreate(self, event): """ executed when the user presses the Create button """ # ask for filename dialog = wx.FileDialog(None, message='Save the configuration file as...', defaultDir=self.defaultPath, wildcard=('*.%s' % version.name), style=wx.SAVE | wx.FD_OVERWRITE_PROMPT) if dialog.ShowModal() == wx.ID_OK: # create a default configuration file filename = dialog.GetPath() cfg = Configuration() cfg.save(filename) # finally, update the filename box and the gui self.configText.SetValue(filename) self.checkFilename() def OnLoad(self, event): """ executed when the user presses the Load button """ # show a file picker dialog dialog = wx.FileDialog(None, message='Select a configuration file', defaultDir=self.defaultPath, wildcard=('*.%s' % version.name), style=wx.OPEN) if dialog.ShowModal() == wx.ID_OK: self.configText.SetValue(dialog.GetPath()) self.checkFilename() def OnDisable(self, event): """ executed when the user presses the Disable button """ # close without a configuration filename (thus disable the plugin) self.app.result = (None, False, False, False, 0) self.Destroy() def OnOK(self, event): """ executed when the user presses the OK button """ # fetch the options if self.checkFilename(): self.app.result = (self.configText.GetValue(), self.checkLevels.GetValue(), self.checkVehicles.GetValue(), self.checkTimeseries.GetValue(), self.slowdownSpin.GetValue()) self.Destroy()
def get_specific_widget(self, parent): from wx.lib.agw.floatspin import FloatSpin self.widget = FloatSpin(parent, -1, value = self.value, min_val = self.min, max_val = self.max, increment = self.increment, digits = 2) return self.widget
class RingSettingsPanel(wx.Panel): def __init__(self, *args, **kwds): # XXX Support several rings. Plot radial distribution somewhere # (not here), but maybe distribution along ring. Drop-down menu # for ring center, and button to reset to beam center. super(RingSettingsPanel, self).__init__(*args, **kwds) # Needed to draw and delete the rings. XXX Applies to # calibration_frame as well? self._pyslip = self.GetParent().GetParent().pyslip sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) # Number of decimal digits for distances. self.digits = 2 # Distance control XXX probably does not belong here # print "DISTANCE",self.GetParent().GetParent().viewer._img # box = wx.BoxSizer(wx.HORIZONTAL) # from wxtbx.phil_controls.floatctrl import FloatCtrl # from wxtbx.phil_controls import EVT_PHIL_CONTROL # self.distance_ctrl = FloatCtrl(self, pos=(300,180), size=(80,-1), # value=80.00, # name="Detector Distance") # self.distance_ctrl.SetMax(1000) # self.distance_ctrl.SetMin(5) # self.distance_ctrl.SetOptional(False) # box.Add(self.distance_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # txtd = wx.StaticText(self, label="Detector Distance") # box.Add(txtd, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # s.Add(box) from wx.lib.agw.floatspin import EVT_FLOATSPIN, FloatSpin # XXX Should really make value be in Aangstroem resolution, and # have a non-linear slider. self._radius = 100 self._center = [0, 0] radius_max = 2000 radius_min = 10 # Radius controls. box = wx.BoxSizer(wx.HORIZONTAL) self.slider = wx.Slider( self, maxValue=radius_max, minValue=radius_min, size=(250, -1), style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL, value=self._radius, ) box.Add(self.slider, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_SLIDER, self.OnSlide, self.slider) self.spinner = FloatSpin( self, digits=self.digits, max_val=radius_max, min_val=radius_min, value=self._radius, ) box.Add(self.spinner, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(EVT_FLOATSPIN, self.OnSpin, self.spinner) self.auto = wx.Button(self, label="Auto fit") self.Bind(wx.EVT_BUTTON, self.OnAutoFit, self.auto) box.Add(self.auto, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) sizer.Add(box) # Centering controls. box = wx.BoxSizer(wx.HORIZONTAL) self.spinner_fast = FloatSpin(self, digits=self.digits, name="fast_ctrl", value=self._center[0]) box.Add( self.spinner_fast, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center fast"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_fast) self.spinner_slow = FloatSpin(self, digits=self.digits, name="slow_ctrl", value=self._center[1]) box.Add( self.spinner_slow, 0, wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5, ) box.Add( wx.StaticText(self, label="Center slow"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5, ) self.Bind(EVT_FLOATSPIN, self.OnSpinCenter, self.spinner_slow) sizer.Add(box) self.DrawRing() def __del__(self): if hasattr(self, "_ring_layer") and self._ring_layer is not None: self._pyslip.DeleteLayer(self._ring_layer) def OnSlide(self, event): # Keep slider and spinner synchronized. obj = event.EventObject # XXX Is this construct sane? See below # and in calibration_frame, too! self._radius = obj.GetValue() self.spinner.SetValue(self._radius) self.DrawRing() def OnAutoFit(self, event): jitter = 6 detector = self._pyslip.tiles.raw_image.get_detector() beam = self._pyslip.tiles.raw_image.get_beam() # FIXME assumes all detector elements use the same millimeter-to-pixel convention if detector[0].get_distance() > 0: if len(detector) > 1: h = detector.hierarchy() if len(h) > 0: beam_pixel_fast, beam_pixel_slow = detector[ 0].millimeter_to_pixel( detector.hierarchy().get_beam_centre( beam.get_s0())) else: beam_pixel_fast, beam_pixel_slow = detector[ 0].millimeter_to_pixel(detector[0].get_beam_centre( beam.get_s0())) else: beam_pixel_fast, beam_pixel_slow = detector[ 0].millimeter_to_pixel(detector[0].get_beam_centre( beam.get_s0())) avg_distance = -sum(p.get_distance() for p in detector) / len(detector) beam_pixel_fast += self._center[0] beam_pixel_slow += self._center[1] def PointsOnCircle(center, radius, count): for r in range(count): t = (r / count) * 2 * math.pi yield ( center[0] + (radius * math.cos(t)), center[1] + (radius * math.sin(t)), ) best = float("-inf") bestc = [self._center[0], self._center[1]] bestr = self._radius image_data = self._pyslip.tiles.raw_image.get_image_data() if not isinstance(image_data, tuple): image_data = (image_data, ) for j in range(-jitter, jitter, 1): j /= 2 for i in range(-jitter, jitter, 1): i /= 2 for r in range(-jitter, jitter, 1): r /= 2 total = 0.0 for point in PointsOnCircle( (beam_pixel_fast + i, beam_pixel_slow + j), self._radius + r, 360, ): mm = detector[0].pixel_to_millimeter(point) mm = (mm[0], mm[1], avg_distance) pid = detector.get_panel_intersection(mm) if pid >= 0: px = detector[pid].get_ray_intersection_px(mm) px = [int(round(px[0])), int(round(px[1]))] data = image_data[pid] if (px[0] >= 0 and px[0] < data.focus()[1] and px[1] >= 0 and px[1] < data.focus()[0]): total += data[px[1], px[0]] if total > best: best = total bestc = [self._center[0] + i, self._center[1] + j] bestr = self._radius + r print("r: % 3.1f, i: % 3.1f, j: % 3.1f, best: %f" % (r, i, j, best)) print("DONE", bestc, bestr) self._radius = bestr self._center = bestc self.spinner.SetValue(bestr) self.spinner_fast.SetValue(bestc[0]) self.spinner_slow.SetValue(bestc[1]) self.DrawRing() def OnSpin(self, event): # Keep slider and spinner synchronized. XXX OnSpinRadius()? obj = event.EventObject self._radius = obj.GetValue() self.slider.SetValue(self._radius) self.DrawRing() def OnSpinCenter(self, event): obj = event.EventObject name = obj.GetName() if name == "fast_ctrl": self._center[0] = obj.GetValue() elif name == "slow_ctrl": self._center[1] = obj.GetValue() self.DrawRing() def _draw_ring_layer(self, dc, data, map_rel): """Draw a points layer. dc the device context to draw on data an iterable of point tuples: (x, y, place, radius, colour, x_off, y_off, pdata) map_rel points relative to map if True, MUST BE TRUE for lightweight Assumes all points are the same colour, saving 100's of ms. """ assert map_rel is True if len(data) == 0: return (lon, lat, place, radius, colour, x_off, y_off, pdata) = data[0] scale = 2**self._pyslip.tiles.zoom_level # Draw points on map/view, using transparency if implemented. try: dc = wx.GCDC(dc) except NotImplementedError: pass dc.SetPen(wx.Pen(colour)) dc.SetBrush(wx.Brush(colour, wx.TRANSPARENT)) for (lon, lat, place, radius, colour, x_off, y_off, pdata) in data: (x, y) = self._pyslip.ConvertGeo2View((lon, lat)) dc.DrawCircle(x, y, radius * scale) def DrawRing(self): detector = self._pyslip.tiles.raw_image.get_detector() xrayframe = self.GetParent().GetParent() panel_id, beam_pixel_fast, beam_pixel_slow = xrayframe.get_beam_center_px( ) if len(detector) > 1: ( beam_pixel_slow, beam_pixel_fast, ) = xrayframe.pyslip.tiles.flex_image.tile_readout_to_picture( panel_id, beam_pixel_slow - 0.5, beam_pixel_fast - 0.5) center = self._pyslip.tiles.picture_fast_slow_to_map_relative( beam_pixel_fast + self._center[0], beam_pixel_slow + self._center[1]) # XXX Transparency? ring_data = [(center[0], center[1], { "colour": "red", "radius": self._radius })] # Remove the old ring layer, and draw a new one. XXX Why # disappears at highest levels? if hasattr(self, "_ring_layer") and self._ring_layer is not None: self._pyslip.DeleteLayer(self._ring_layer) self._ring_layer = None self._ring_layer = self._pyslip.AddPointLayer( ring_data, map_rel=True, visible=True, show_levels=[-3, -2, -1, 0, 1, 2, 3, 4, 5], renderer=self._draw_ring_layer, name="<ring_layer>", )
def __init__(self, parent, id=-1, title='Preferences', style=wx.DEFAULT_DIALOG_STYLE, major_increment=0.75, minor_increment=0.1): super(PreferencesDialog, self).__init__(parent, id, title, (-1, -1), (-1, -1), style) self.SetBackgroundColour('black') labelFont = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False) # Spinners for setting the increments self.maj_increment_spin = FloatSpin(self, wx.ID_ANY, value=major_increment, digits=2, increment=0.1, size=(65, -1)) # Button maj_label = wx.StaticText(self, wx.ID_ANY, 'Major Increment', style=wx.ALIGN_CENTER) # Label maj_label.SetForegroundColour('white') maj_label.SetFont(labelFont) self.min_increment_spin = FloatSpin(self, wx.ID_ANY, value=minor_increment, digits=2, increment=0.1, size=(65, -1)) # Button min_label = wx.StaticText(self, wx.ID_ANY, 'Minor Increment', style=wx.ALIGN_CENTER) # Label min_label.SetForegroundColour('white') min_label.SetFont(labelFont) # To keep the items properly aligned major_increment_sizer = wx.BoxSizer(wx.HORIZONTAL) minor_increment_sizer = wx.BoxSizer(wx.HORIZONTAL) major_increment_sizer.Add(maj_label, 0, wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT, 10) major_increment_sizer.AddSpacer(6) major_increment_sizer.Add(self.maj_increment_spin, 0, wx.ALIGN_LEFT | wx.BOTTOM | wx.RIGHT, 10) minor_increment_sizer.Add(min_label, 0, wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT, 10) minor_increment_sizer.AddSpacer(6) minor_increment_sizer.Add(self.min_increment_spin, 0, wx.ALIGN_LEFT | wx.BOTTOM | wx.RIGHT, 10) # OK/Cancel bar self.ok_button = wx.Button(self, id=wx.OK, label="OK", size=(65, -1)) self.ok_button.SetBackgroundColour('medium gray') self.ok_button.SetForegroundColour('white') self.ok_button.Bind(wx.EVT_BUTTON, self.on_okay) self.cancel_button = wx.Button(self, id=wx.CANCEL, label="Cancel", size=(65, -1)) self.cancel_button.SetBackgroundColour('medium gray') self.cancel_button.SetForegroundColour('white') self.cancel_button.Bind(wx.EVT_BUTTON, self.on_cancel) okbar_sizer = wx.BoxSizer(wx.HORIZONTAL) okbar_sizer.Add(self.ok_button, 0, wx.ALIGN_LEFT | wx.BOTTOM | wx.LEFT, 2) okbar_sizer.AddSpacer(20) okbar_sizer.Add(self.cancel_button, 0, wx.ALIGN_RIGHT | wx.BOTTOM | wx.RIGHT, 2) sizer = wx.GridBagSizer() sizer.AddGrowableCol(0, 4) sizer.Add(major_increment_sizer, (0, 0), (1, 2), wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add(minor_increment_sizer, (1, 0), (1, 2), wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add(okbar_sizer, (2, 0), (1, 2), wx.ALIGN_CENTER | wx.ALL, 5) self.SetSizerAndFit(sizer) self.SetAffirmativeId(wx.OK) self.SetEscapeId(wx.CANCEL) self.AddMainButtonId(wx.OK)
class ch6VoltageSourceTunerDialog(Dialog): """ A dialog for tuning a voltage source port. """ def __init__(self, parent, global_store, ok_callback, port, *args, **kwargs): Dialog.__init__(self, parent, title='Port {0} tuning'.format(port.num)) self.global_store = global_store self.ok_callback = ok_callback self.port = port # Dialog. dialog_box = wx.BoxSizer(wx.VERTICAL) ## Self-calibration. calibration_static_box = wx.StaticBox(self, label='DAC self-calibration') calibration_box = wx.StaticBoxSizer(calibration_static_box, wx.VERTICAL) dialog_box.Add(calibration_box, flag=wx.EXPAND | wx.ALL, border=5) self.calibrate_button = wx.Button(self, label='Self-calibrate') self.Bind(wx.EVT_BUTTON, self.OnCalibrate, self.calibrate_button) calibration_box.Add(self.calibrate_button, flag=wx.EXPAND) ## Tuning. tuning_static_box = wx.StaticBox(self, label='Tuning') tuning_box = wx.StaticBoxSizer(tuning_static_box, wx.VERTICAL) dialog_box.Add(tuning_box, flag=wx.EXPAND) ### Autotune. autotuning_static_box = wx.StaticBox(self, label='Autotuning') autotuning_box = wx.StaticBoxSizer(autotuning_static_box, wx.VERTICAL) tuning_box.Add(autotuning_box, flag=wx.EXPAND | wx.ALL, border=5) autotuning_sizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5) autotuning_box.Add(autotuning_sizer, flag=wx.CENTER) autotuning_sizer.Add(wx.StaticText(self, label='Resource name:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.resource_name_input = wx.TextCtrl(self, size=(300, -1)) autotuning_sizer.Add(self.resource_name_input) autotuning_sizer.Add(wx.StaticText(self, label='Max:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.automax_input = FloatSpin(self, value=1, min_val=-10, max_val=10, increment=1, digits=5) autotuning_sizer.Add(self.automax_input) autotuning_sizer.Add(wx.StaticText(self, label='Min:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.automin_input = FloatSpin(self, value=-1, min_val=-10, max_val=10, increment=1, digits=5) autotuning_sizer.Add(self.automin_input) self.autotune_button = wx.Button(self, label='Autotune') self.Bind(wx.EVT_BUTTON, self.OnAutotune, self.autotune_button) autotuning_box.Add(self.autotune_button, flag=wx.EXPAND) ### Manual tune. tuning_sizer = wx.FlexGridSizer(rows=2, cols=2, hgap=5) tuning_box.Add(tuning_sizer, flag=wx.CENTER) tuning_sizer.Add(wx.StaticText(self, label='Gain:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.gain_input = FloatSpin(self, value=0, min_val=-1e6, max_val=1e6, increment=1, digits=5) tuning_sizer.Add(self.gain_input) tuning_sizer.Add(wx.StaticText(self, label='Offset:'), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) self.offset_input = FloatSpin(self, value=0, min_val=-1e6, max_val=1e6, increment=1, digits=5) tuning_sizer.Add(self.offset_input) ## End buttons. button_box = wx.BoxSizer(wx.HORIZONTAL) dialog_box.Add(button_box, flag=wx.CENTER | wx.ALL, border=5) ok_button = wx.Button(self, wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.OnOk, ok_button) button_box.Add(ok_button) cancel_button = wx.Button(self, wx.ID_CANCEL) button_box.Add(cancel_button) self.SetSizerAndFit(dialog_box) def autotune(self, resource): gain, offset = self.port.autotune( resource, set_result=False, min_value=self.automin_input.GetValue(), max_value=self.automax_input.GetValue()) wx.CallAfter(self.gain_input.SetValue, gain) wx.CallAfter(self.offset_input.SetValue, offset) wx.CallAfter(self.autotune_button.Enable) def self_calbrate(self): self.port.apply_settings(calibrate=True) sleep(self.port.calibration_delay) wx.CallAfter(self.calibrate_button.Enable) def SetValue(self, gain, offset): self.gain_input.SetValue(gain) self.offset_input.SetValue(offset) def GetValue(self): return (self.gain_input.GetValue(), self.offset_input.GetValue()) def OnAutotune(self, evt=None): name = self.resource_name_input.Value if not name: MessageDialog(self, 'No resource provided').Show() return try: resource = self.global_store.resources[name] except KeyError: MessageDialog(self, name, 'Missing resource').Show() return if not resource.readable: MessageDialog(self, name, 'Unreadable resource').Show() return self.autotune_button.Disable() thr = Thread(target=self.autotune, args=(resource, )) thr.daemon = True thr.start() def OnCalibrate(self, evt=None): self.calibrate_button.Disable() thr = Thread(target=self.self_calbrate) thr.daemon = True thr.start() def OnOk(self, evt=None): self.ok_callback(self) self.Destroy()
class YAxisRangeBox(wx.Panel): """ panel for adjusting y-axis range """ def __init__(self, parent, ID, minvalue=YMIN, initvalue=YRANGE, increment=SPININC): wx.Panel.__init__(self, parent, ID) self.value = initvalue # initial y-axis range (in manual mode), i.e. (min, max-min) # controls self.radio_auto = wx.RadioButton(self, -1, label='Auto', style=wx.RB_GROUP) self.radio_manual = wx.RadioButton(self, -1, label='Manual') self.manual_min = FloatSpin(self, -1, size=(50, -1), digits=0, value=self.value[0], min_val=minvalue[0], increment=increment) self.manual_min.GetTextCtrl().SetEditable(False) self.manual_width = FloatSpin(self, -1, size=(50, -1), digits=0, value=self.value[1], min_val=minvalue[1], increment=increment) self.manual_width.GetTextCtrl().SetEditable(False) # event bindings self.Bind(wx.EVT_UPDATE_UI, self.on_update_radio_buttons, self.radio_auto) self.Bind(EVT_FLOATSPIN, self.on_float_spin, self.manual_min) self.Bind(EVT_FLOATSPIN, self.on_float_spin, self.manual_width) # layout box = wx.StaticBox(self, -1, 'Y-axis') sizer = wx.StaticBoxSizer(box, wx.VERTICAL) manual_box = wx.BoxSizer(wx.HORIZONTAL) manual_box.Add(self.radio_manual, flag=wx.ALIGN_CENTER_VERTICAL) manual_box.Add(self.manual_min, flag=wx.ALIGN_CENTER_VERTICAL) manual_box.Add(self.manual_width, flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.radio_auto, 0, wx.ALL, 10) sizer.Add(manual_box, 0, wx.ALL, 10) self.SetSizer(sizer) sizer.Fit(self) def on_update_radio_buttons(self, event): """ called when the radio buttons are toggled """ toggle = self.radio_manual.GetValue() self.manual_min.Enable(toggle) self.manual_width.Enable(toggle) def on_float_spin(self, event): """ called when one of the manual mode spinboxes is changed """ self.value = (self.manual_min.GetValue(), self.manual_width.GetValue()) def is_auto(self): """ return True if auto range is checked """ return self.radio_auto.GetValue()