class DialogExportGeo(wx.Dialog): IMAGE_SIZE = 500 def __init__(self, parent, spectrum, location, settings): self.spectrum = spectrum self.location = location self.settings = settings self.directory = settings.dirExport self.colourMap = settings.colourMap self.colourHeat = settings.colourMap self.canvas = None self.extent = None self.xyz = None self.plotAxes = False self.plotMesh = True self.plotCont = True self.plotPoint = False self.plotHeat = False self.plot = None wx.Dialog.__init__(self, parent=parent, title='Export Map') colours = get_colours() freqMin = min(spectrum[min(spectrum)]) * 1000 freqMax = max(spectrum[min(spectrum)]) * 1000 bw = freqMax - freqMin self.figure = matplotlib.figure.Figure(facecolor='white') self.figure.set_size_inches((6, 6)) self.canvas = FigureCanvas(self, -1, self.figure) self.axes = self.figure.add_subplot(111) if matplotlib.__version__ >= '1.2': self.figure.tight_layout() self.figure.subplots_adjust(left=0, right=1, top=1, bottom=0) textPlot = wx.StaticText(self, label='Plot') self.checkAxes = wx.CheckBox(self, label='Axes') self.checkAxes.SetValue(self.plotAxes) self.Bind(wx.EVT_CHECKBOX, self.__on_axes, self.checkAxes) self.checkCont = wx.CheckBox(self, label='Contour lines') self.checkCont.SetValue(self.plotCont) self.Bind(wx.EVT_CHECKBOX, self.__on_cont, self.checkCont) self.checkPoint = wx.CheckBox(self, label='Locations') self.checkPoint.SetValue(self.plotPoint) self.Bind(wx.EVT_CHECKBOX, self.__on_point, self.checkPoint) sizerPlotCheck = wx.BoxSizer(wx.HORIZONTAL) sizerPlotCheck.Add(self.checkAxes, flag=wx.ALL, border=5) sizerPlotCheck.Add(self.checkCont, flag=wx.ALL, border=5) sizerPlotCheck.Add(self.checkPoint, flag=wx.ALL, border=5) sizerPlot = wx.BoxSizer(wx.VERTICAL) sizerPlot.Add(textPlot, flag=wx.ALL, border=5) sizerPlot.Add(sizerPlotCheck, flag=wx.ALL, border=5) textMesh = wx.StaticText(self, label='Mesh') self.checkMesh = wx.CheckBox(self, label='On') self.checkMesh.SetToolTipString('Signal level mesh') self.checkMesh.SetValue(self.plotMesh) self.Bind(wx.EVT_CHECKBOX, self.__on_mesh, self.checkMesh) self.choiceMapMesh = wx.Choice(self, choices=colours) self.choiceMapMesh.SetSelection(colours.index(self.colourMap)) self.Bind(wx.EVT_CHOICE, self.__on_colour_mesh, self.choiceMapMesh) self.barMesh = PanelColourBar(self, self.colourMap) sizerMapMesh = wx.BoxSizer(wx.HORIZONTAL) sizerMapMesh.Add(self.choiceMapMesh, flag=wx.ALL, border=5) sizerMapMesh.Add(self.barMesh, flag=wx.ALL, border=5) sizerMesh = wx.BoxSizer(wx.VERTICAL) sizerMesh.Add(textMesh, flag=wx.ALL, border=5) sizerMesh.Add(self.checkMesh, flag=wx.ALL, border=5) sizerMesh.Add(sizerMapMesh, flag=wx.ALL, border=5) colours = get_colours() textHeat = wx.StaticText(self, label='Heat map') self.checkHeat = wx.CheckBox(self, label='On') self.checkHeat.SetToolTipString('GPS location heatmap') self.checkHeat.SetValue(self.plotHeat) self.Bind(wx.EVT_CHECKBOX, self.__on_heat, self.checkHeat) self.choiceMapHeat = wx.Choice(self, choices=colours) self.choiceMapHeat.SetSelection(colours.index(self.colourHeat)) self.Bind(wx.EVT_CHOICE, self.__on_colour_heat, self.choiceMapHeat) self.barHeat = PanelColourBar(self, self.colourHeat) sizerMapHeat = wx.BoxSizer(wx.HORIZONTAL) sizerMapHeat.Add(self.choiceMapHeat, flag=wx.ALL, border=5) sizerMapHeat.Add(self.barHeat, flag=wx.ALL, border=5) sizerHeat = wx.BoxSizer(wx.VERTICAL) sizerHeat.Add(textHeat, flag=wx.ALL, border=5) sizerHeat.Add(self.checkHeat, flag=wx.ALL, border=5) sizerHeat.Add(sizerMapHeat, flag=wx.ALL, border=5) textRange = wx.StaticText(self, label='Range') textCentre = wx.StaticText(self, label='Centre') self.spinCentre = wx.SpinCtrl(self) self.spinCentre.SetToolTipString('Centre frequency (kHz)') self.spinCentre.SetRange(freqMin, freqMax) self.spinCentre.SetValue(freqMin + bw / 2) sizerCentre = wx.BoxSizer(wx.HORIZONTAL) sizerCentre.Add(textCentre, flag=wx.ALL, border=5) sizerCentre.Add(self.spinCentre, flag=wx.ALL, border=5) textBw = wx.StaticText(self, label='Bandwidth') self.spinBw = wx.SpinCtrl(self) self.spinBw.SetToolTipString('Bandwidth (kHz)') self.spinBw.SetRange(1, bw) self.spinBw.SetValue(bw / 10) sizerBw = wx.BoxSizer(wx.HORIZONTAL) sizerBw.Add(textBw, flag=wx.ALL, border=5) sizerBw.Add(self.spinBw, flag=wx.ALL, border=5) buttonUpdate = wx.Button(self, label='Update') self.Bind(wx.EVT_BUTTON, self.__on_update, buttonUpdate) sizerRange = wx.BoxSizer(wx.VERTICAL) sizerRange.Add(textRange, flag=wx.ALL, border=5) sizerRange.Add(sizerCentre, flag=wx.ALL, border=5) sizerRange.Add(sizerBw, flag=wx.ALL, border=5) sizerRange.Add(buttonUpdate, flag=wx.ALL, border=5) textOutput = wx.StaticText(self, label='Output') self.textRes = wx.StaticText(self) buttonRes = wx.Button(self, label='Change...') buttonRes.SetToolTipString('Change output resolution') self.Bind(wx.EVT_BUTTON, self.__on_imageres, buttonRes) sizerRes = wx.BoxSizer(wx.HORIZONTAL) sizerRes.Add(self.textRes, flag=wx.ALL, border=5) sizerRes.Add(buttonRes, flag=wx.ALL, border=5) sizerOutput = wx.BoxSizer(wx.VERTICAL) sizerOutput.Add(textOutput, flag=wx.ALL, border=5) sizerOutput.Add(sizerRes, flag=wx.ALL, border=5) self.__show_image_res() font = textPlot.GetFont() fontSize = font.GetPointSize() font.SetPointSize(fontSize + 4) textPlot.SetFont(font) textMesh.SetFont(font) textHeat.SetFont(font) textRange.SetFont(font) textOutput.SetFont(font) sizerButtons = wx.StdDialogButtonSizer() buttonOk = wx.Button(self, wx.ID_OK) buttonCancel = wx.Button(self, wx.ID_CANCEL) sizerButtons.AddButton(buttonOk) sizerButtons.AddButton(buttonCancel) sizerButtons.Realize() self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk) self.__setup_plot() sizerGrid = wx.GridBagSizer(5, 5) sizerGrid.Add(self.canvas, pos=(0, 0), span=(5, 6), flag=wx.EXPAND | wx.ALL, border=5) sizerGrid.Add(sizerPlot, pos=(0, 7), flag=wx.EXPAND | wx.ALL, border=5) sizerGrid.Add(sizerMesh, pos=(1, 7), flag=wx.EXPAND | wx.ALL, border=5) sizerGrid.Add(sizerHeat, pos=(2, 7), flag=wx.EXPAND | wx.ALL, border=5) sizerGrid.Add(sizerRange, pos=(3, 7), flag=wx.EXPAND | wx.ALL, border=5) sizerGrid.Add(sizerOutput, pos=(4, 7), flag=wx.EXPAND | wx.ALL, border=5) sizerGrid.Add(sizerButtons, pos=(5, 7), span=(1, 2), flag=wx.ALIGN_RIGHT | wx.ALL, border=5) self.SetSizerAndFit(sizerGrid) self.__draw_plot() def __setup_plot(self): self.axes.clear() self.choiceMapMesh.Enable(self.plotMesh) self.choiceMapHeat.Enable(self.plotHeat) self.axes.set_xlabel('Longitude ($^\circ$)') self.axes.set_ylabel('Latitude ($^\circ$)') self.axes.set_xlim(auto=True) self.axes.set_ylim(auto=True) formatter = ScalarFormatter(useOffset=False) self.axes.xaxis.set_major_formatter(formatter) self.axes.yaxis.set_major_formatter(formatter) def __draw_plot(self): freqCentre = self.spinCentre.GetValue() freqBw = self.spinBw.GetValue() freqMin = (freqCentre - freqBw) / 1000. freqMax = (freqCentre + freqBw) / 1000. coords = {} for timeStamp in self.spectrum: spectrum = self.spectrum[timeStamp] sweep = [yv for xv, yv in spectrum.items() if freqMin <= xv <= freqMax] if len(sweep): peak = max(sweep) try: location = self.location[timeStamp] except KeyError: continue coord = tuple(location[0:2]) if coord not in coords: coords[coord] = peak else: coords[coord] = (coords[coord] + peak) / 2 x = [] y = [] z = [] for coord, peak in coords.iteritems(): x.append(coord[1]) y.append(coord[0]) z.append(peak) self.extent = (min(x), max(x), min(y), max(y)) self.xyz = (x, y, z) xi = numpy.linspace(min(x), max(x), self.IMAGE_SIZE) yi = numpy.linspace(min(y), max(y), self.IMAGE_SIZE) if self.plotMesh or self.plotCont: zi = mlab.griddata(x, y, z, xi, yi) if self.plotMesh: self.plot = self.axes.pcolormesh(xi, yi, zi, cmap=self.colourMap) self.plot.set_zorder(1) if self.plotCont: contours = self.axes.contour(xi, yi, zi, linewidths=0.5, colors='k') self.axes.clabel(contours, inline=1, fontsize='x-small', gid='clabel', zorder=3) if self.plotHeat: image = create_heatmap(x, y, self.IMAGE_SIZE, self.IMAGE_SIZE / 10, self.colourHeat) heatMap = self.axes.imshow(image, aspect='auto', extent=self.extent) heatMap.set_zorder(2) if self.plotPoint: self.axes.plot(x, y, 'wo') for posX, posY, posZ in zip(x, y, z): points = self.axes.annotate('{0:.2f}dB'.format(posZ), xy=(posX, posY), xytext=(-5, 5), ha='right', textcoords='offset points') points.set_zorder(3) if matplotlib.__version__ >= '1.3': effect = patheffects.withStroke(linewidth=2, foreground="w", alpha=0.75) for child in self.axes.get_children(): child.set_path_effects([effect]) if self.plotAxes: self.axes.set_axis_on() else: self.axes.set_axis_off() self.canvas.draw() def __draw_warning(self): self.axes.text(0.5, 0.5, 'Insufficient GPS data', ha='center', va='center', transform=self.axes.transAxes) def __on_update(self, _event): self.__setup_plot() self.__draw_plot() def __on_imageres(self, _event): dlg = DialogImageSize(self, self.settings, True) dlg.ShowModal() self.__show_image_res() def __on_ok(self, _event): self.EndModal(wx.ID_OK) def __on_axes(self, _event): self.plotAxes = self.checkAxes.GetValue() if self.plotAxes: self.axes.set_axis_on() else: self.axes.set_axis_off() self.canvas.draw() def __on_mesh(self, _event): self.plotMesh = self.checkMesh.GetValue() self.__on_update(None) def __on_cont(self, _event): self.plotCont = self.checkCont.GetValue() self.__on_update(None) def __on_point(self, _event): self.plotPoint = self.checkPoint.GetValue() self.__on_update(None) def __on_heat(self, _event): self.plotHeat = self.checkHeat.GetValue() self.__on_update(None) def __on_colour_mesh(self, _event): self.colourMesh = self.choiceMapMesh.GetStringSelection() self.barMesh.set_map(self.colourMesh) if self.plot: self.plot.set_cmap(self.colourMesh) self.canvas.draw() def __on_colour_heat(self, _event): self.colourHeat = self.choiceMapHeat.GetStringSelection() self.barHeat.set_map(self.colourHeat) self.__on_update(None) def __show_image_res(self): self.textRes.SetLabel('{}dpi'.format(self.settings.exportDpi)) def get_filename(self): return self.filename def get_directory(self): return self.directory def get_extent(self): return self.extent def get_image(self): width = self.extent[1] - self.extent[0] height = self.extent[3] - self.extent[2] self.figure.set_size_inches((6, 6. * width / height)) self.figure.set_dpi(self.settings.exportDpi) self.figure.patch.set_alpha(0) self.axes.axesPatch.set_alpha(0) canvas = FigureCanvasAgg(self.figure) canvas.draw() renderer = canvas.get_renderer() if matplotlib.__version__ >= '1.2': buf = renderer.buffer_rgba() else: buf = renderer.buffer_rgba(0, 0) size = canvas.get_width_height() image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1) return image def get_xyz(self): return self.xyz
class DialogPrefs(wx.Dialog): def __init__(self, parent, settings): self.settings = settings self.index = 0 wx.Dialog.__init__(self, parent=parent, title="Preferences") self.colours = get_colours() self.winFunc = settings.winFunc self.background = settings.background self.checkSaved = wx.CheckBox(self, wx.ID_ANY, "Save warning") self.checkSaved.SetValue(settings.saveWarn) self.checkBackup = wx.CheckBox(self, wx.ID_ANY, "Backup") self.checkBackup.SetValue(settings.backup) self.checkBackup.SetToolTipString('Backup data after crash') self.checkAlert = wx.CheckBox(self, wx.ID_ANY, "Level alert (dB)") self.checkAlert.SetValue(settings.alert) self.checkAlert.SetToolTipString('Play alert when level exceeded') self.Bind(wx.EVT_CHECKBOX, self.__on_alert, self.checkAlert) self.spinLevel = wx.SpinCtrl(self, wx.ID_ANY, min=-100, max=20) self.spinLevel.SetValue(settings.alertLevel) self.spinLevel.Enable(settings.alert) self.spinLevel.SetToolTipString('Alert threshold') textBackground = wx.StaticText(self, label='Background colour') self.buttonBackground = wx.Button(self, wx.ID_ANY) self.buttonBackground.SetBackgroundColour(self.background) self.Bind(wx.EVT_BUTTON, self.__on_background, self.buttonBackground) textColour = wx.StaticText(self, label="Colour map") self.choiceColour = wx.Choice(self, choices=self.colours) self.choiceColour.SetSelection(self.colours.index(settings.colourMap)) self.Bind(wx.EVT_CHOICE, self.__on_choice, self.choiceColour) self.colourBar = PanelColourBar(self, settings.colourMap) self.checkPoints = wx.CheckBox(self, wx.ID_ANY, "Limit points") self.checkPoints.SetValue(settings.pointsLimit) self.checkPoints.SetToolTipString('Limit the resolution of plots') self.Bind(wx.EVT_CHECKBOX, self.__on_points, self.checkPoints) self.spinPoints = wx.SpinCtrl(self, wx.ID_ANY, min=1000, max=100000) self.spinPoints.Enable(settings.pointsLimit) self.spinPoints.SetValue(settings.pointsMax) self.spinPoints.SetToolTipString('Maximum number of points to plot_line') textDpi = wx.StaticText(self, label='Export DPI') self.spinDpi = wx.SpinCtrl(self, wx.ID_ANY, min=72, max=6000) self.spinDpi.SetValue(settings.exportDpi) self.spinDpi.SetToolTipString('DPI of exported images') self.checkTune = wx.CheckBox(self, wx.ID_ANY, "Tune SDR#") self.checkTune.SetValue(settings.clickTune) self.checkTune.SetToolTipString('Double click plot_line to tune SDR#') textPlugin = wx.HyperlinkCtrl(self, wx.ID_ANY, label="(Requires plugin)", url="http://eartoearoak.com/software/sdrsharp-net-remote") self.radioAvg = wx.RadioButton(self, wx.ID_ANY, 'Average Scans', style=wx.RB_GROUP) self.radioAvg.SetToolTipString('Average level with each scan') self.Bind(wx.EVT_RADIOBUTTON, self.__on_radio, self.radioAvg) self.radioRetain = wx.RadioButton(self, wx.ID_ANY, 'Retain previous scans') self.radioRetain.SetToolTipString('Can be slow') self.Bind(wx.EVT_RADIOBUTTON, self.__on_radio, self.radioRetain) self.radioRetain.SetValue(settings.retainScans) textMaxScans = wx.StaticText(self, label="Max scans") self.spinCtrlMaxScans = wx.SpinCtrl(self) self.spinCtrlMaxScans.SetRange(1, 5000) self.spinCtrlMaxScans.SetValue(settings.retainMax) self.spinCtrlMaxScans.SetToolTipString('Maximum previous scans' ' to display') textWidth = wx.StaticText(self, label="Line width") self.ctrlWidth = NumCtrl(self, integerWidth=2, fractionWidth=1) self.ctrlWidth.SetValue(settings.lineWidth) self.__on_radio(None) sizerButtons = wx.StdDialogButtonSizer() buttonOk = wx.Button(self, wx.ID_OK) buttonCancel = wx.Button(self, wx.ID_CANCEL) sizerButtons.AddButton(buttonOk) sizerButtons.AddButton(buttonCancel) sizerButtons.Realize() self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk) gengrid = wx.GridBagSizer(10, 10) gengrid.Add(self.checkSaved, pos=(0, 0)) gengrid.Add(self.checkBackup, pos=(1, 0)) gengrid.Add(self.checkAlert, pos=(2, 0), flag=wx.ALIGN_CENTRE) gengrid.Add(self.spinLevel, pos=(2, 1)) gengrid.Add(textBackground, pos=(3, 0), flag=wx.ALIGN_CENTRE) gengrid.Add(self.buttonBackground, pos=(3, 1)) gengrid.Add(textColour, pos=(4, 0)) gengrid.Add(self.choiceColour, pos=(4, 1)) gengrid.Add(self.colourBar, pos=(4, 2)) gengrid.Add(self.checkPoints, pos=(5, 0)) gengrid.Add(self.spinPoints, pos=(5, 1)) gengrid.Add(textDpi, pos=(6, 0)) gengrid.Add(self.spinDpi, pos=(6, 1)) gengrid.Add(self.checkTune, pos=(7, 0)) gengrid.Add(textPlugin, pos=(7, 1)) genbox = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "General")) genbox.Add(gengrid, 0, wx.ALL | wx.ALIGN_CENTRE_VERTICAL, 10) congrid = wx.GridBagSizer(10, 10) congrid.Add(self.radioAvg, pos=(0, 0)) congrid.Add(self.radioRetain, pos=(1, 0)) congrid.Add(textMaxScans, pos=(2, 0), flag=wx.ALIGN_CENTRE_VERTICAL) congrid.Add(self.spinCtrlMaxScans, pos=(2, 1)) conbox = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Continuous Scans"), wx.VERTICAL) conbox.Add(congrid, 0, wx.ALL | wx.EXPAND, 10) plotgrid = wx.GridBagSizer(10, 10) plotgrid.Add(textWidth, pos=(0, 0)) plotgrid.Add(self.ctrlWidth, pos=(0, 1)) plotbox = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Plot View"), wx.HORIZONTAL) plotbox.Add(plotgrid, 0, wx.ALL | wx.EXPAND, 10) grid = wx.GridBagSizer(10, 10) grid.Add(genbox, pos=(0, 0), span=(1, 2), flag=wx.EXPAND) grid.Add(conbox, pos=(1, 0), span=(1, 2), flag=wx.EXPAND) grid.Add(plotbox, pos=(2, 0), span=(1, 2), flag=wx.EXPAND) grid.Add(sizerButtons, pos=(3, 1), flag=wx.EXPAND) box = wx.BoxSizer() box.Add(grid, flag=wx.ALL | wx.ALIGN_CENTRE, border=10) self.SetSizerAndFit(box) def __on_alert(self, _event): enabled = self.checkAlert.GetValue() self.spinLevel.Enable(enabled) def __on_points(self, _event): enabled = self.checkPoints.GetValue() self.spinPoints.Enable(enabled) def __on_background(self, _event): colour = wx.ColourData() colour.SetColour(self.background) dlg = CubeColourDialog(self, colour, 0) if dlg.ShowModal() == wx.ID_OK: newColour = dlg.GetColourData().GetColour() self.background = newColour.GetAsString(wx.C2S_HTML_SYNTAX) self.buttonBackground.SetBackgroundColour(self.background) dlg.Destroy() def __on_radio(self, _event): enabled = self.radioRetain.GetValue() self.spinCtrlMaxScans.Enable(enabled) def __on_choice(self, _event): self.colourBar.set_map(self.choiceColour.GetStringSelection()) self.choiceColour.SetFocus() def __on_ok(self, _event): self.settings.saveWarn = self.checkSaved.GetValue() self.settings.backup = self.checkBackup.GetValue() self.settings.alert = self.checkAlert.GetValue() self.settings.alertLevel = self.spinLevel.GetValue() self.settings.clickTune = self.checkTune.GetValue() self.settings.pointsLimit = self.checkPoints.GetValue() self.settings.pointsMax = self.spinPoints.GetValue() self.settings.exportDpi = self.spinDpi.GetValue() self.settings.retainScans = self.radioRetain.GetValue() self.settings.lineWidth = self.ctrlWidth.GetValue() self.settings.retainMax = self.spinCtrlMaxScans.GetValue() self.settings.colourMap = self.choiceColour.GetStringSelection() self.settings.background = self.background self.EndModal(wx.ID_OK)
class DialogPrefs(wx.Dialog): def __init__(self, parent, settings): self.settings = settings self.index = 0 wx.Dialog.__init__(self, parent=parent, title="Preferences") self.colours = get_colours() self.winFunc = settings.winFunc self.background = settings.background self.checkSaved = wx.CheckBox(self, wx.ID_ANY, "Save warning") self.checkSaved.SetValue(settings.saveWarn) self.checkBackup = wx.CheckBox(self, wx.ID_ANY, "Backup") self.checkBackup.SetValue(settings.backup) self.checkBackup.SetToolTipString('Backup data after crash') self.checkAlert = wx.CheckBox(self, wx.ID_ANY, "Level alert (dB)") self.checkAlert.SetValue(settings.alert) self.checkAlert.SetToolTipString('Play alert when level exceeded') self.Bind(wx.EVT_CHECKBOX, self.__on_alert, self.checkAlert) self.spinLevel = wx.SpinCtrl(self, wx.ID_ANY, min=-100, max=20) self.spinLevel.SetValue(settings.alertLevel) self.spinLevel.Enable(settings.alert) self.spinLevel.SetToolTipString('Alert threshold') textBackground = wx.StaticText(self, label='Background colour') self.buttonBackground = wx.Button(self, wx.ID_ANY) self.buttonBackground.SetBackgroundColour(self.background) self.Bind(wx.EVT_BUTTON, self.__on_background, self.buttonBackground) textColour = wx.StaticText(self, label="Colour map") self.choiceColour = wx.Choice(self, choices=self.colours) self.choiceColour.SetSelection(self.colours.index(settings.colourMap)) self.Bind(wx.EVT_CHOICE, self.__on_choice, self.choiceColour) self.colourBar = PanelColourBar(self, settings.colourMap) self.checkPoints = wx.CheckBox(self, wx.ID_ANY, "Limit points") self.checkPoints.SetValue(settings.pointsLimit) self.checkPoints.SetToolTipString('Limit the resolution of plots') self.Bind(wx.EVT_CHECKBOX, self.__on_points, self.checkPoints) self.spinPoints = wx.SpinCtrl(self, wx.ID_ANY, min=1000, max=100000) self.spinPoints.Enable(settings.pointsLimit) self.spinPoints.SetValue(settings.pointsMax) self.spinPoints.SetToolTipString( 'Maximum number of points to plot_line') textDpi = wx.StaticText(self, label='Export DPI') self.spinDpi = wx.SpinCtrl(self, wx.ID_ANY, min=72, max=6000) self.spinDpi.SetValue(settings.exportDpi) self.spinDpi.SetToolTipString('DPI of exported images') self.checkTune = wx.CheckBox(self, wx.ID_ANY, "Tune SDR#") self.checkTune.SetValue(settings.clickTune) self.checkTune.SetToolTipString('Double click plot_line to tune SDR#') textPlugin = wx.HyperlinkCtrl( self, wx.ID_ANY, label="(Requires plugin)", url="http://eartoearoak.com/software/sdrsharp-net-remote") self.radioAvg = wx.RadioButton(self, wx.ID_ANY, 'Average Scans', style=wx.RB_GROUP) self.radioAvg.SetToolTipString('Average level with each scan') self.Bind(wx.EVT_RADIOBUTTON, self.__on_radio, self.radioAvg) self.radioRetain = wx.RadioButton(self, wx.ID_ANY, 'Retain previous scans') self.radioRetain.SetToolTipString('Can be slow') self.Bind(wx.EVT_RADIOBUTTON, self.__on_radio, self.radioRetain) self.radioRetain.SetValue(settings.retainScans) textMaxScans = wx.StaticText(self, label="Max scans") self.spinCtrlMaxScans = wx.SpinCtrl(self) self.spinCtrlMaxScans.SetRange(1, 5000) self.spinCtrlMaxScans.SetValue(settings.retainMax) self.spinCtrlMaxScans.SetToolTipString('Maximum previous scans' ' to display') textWidth = wx.StaticText(self, label="Line width") self.ctrlWidth = NumCtrl(self, integerWidth=2, fractionWidth=1) self.ctrlWidth.SetValue(settings.lineWidth) self.__on_radio(None) sizerButtons = wx.StdDialogButtonSizer() buttonOk = wx.Button(self, wx.ID_OK) buttonCancel = wx.Button(self, wx.ID_CANCEL) sizerButtons.AddButton(buttonOk) sizerButtons.AddButton(buttonCancel) sizerButtons.Realize() self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk) gengrid = wx.GridBagSizer(10, 10) gengrid.Add(self.checkSaved, pos=(0, 0)) gengrid.Add(self.checkBackup, pos=(1, 0)) gengrid.Add(self.checkAlert, pos=(2, 0), flag=wx.ALIGN_CENTRE) gengrid.Add(self.spinLevel, pos=(2, 1)) gengrid.Add(textBackground, pos=(3, 0), flag=wx.ALIGN_CENTRE) gengrid.Add(self.buttonBackground, pos=(3, 1)) gengrid.Add(textColour, pos=(4, 0)) gengrid.Add(self.choiceColour, pos=(4, 1)) gengrid.Add(self.colourBar, pos=(4, 2)) gengrid.Add(self.checkPoints, pos=(5, 0)) gengrid.Add(self.spinPoints, pos=(5, 1)) gengrid.Add(textDpi, pos=(6, 0)) gengrid.Add(self.spinDpi, pos=(6, 1)) gengrid.Add(self.checkTune, pos=(7, 0)) gengrid.Add(textPlugin, pos=(7, 1)) genbox = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "General")) genbox.Add(gengrid, 0, wx.ALL | wx.ALIGN_CENTRE_VERTICAL, 10) congrid = wx.GridBagSizer(10, 10) congrid.Add(self.radioAvg, pos=(0, 0)) congrid.Add(self.radioRetain, pos=(1, 0)) congrid.Add(textMaxScans, pos=(2, 0), flag=wx.ALIGN_CENTRE_VERTICAL) congrid.Add(self.spinCtrlMaxScans, pos=(2, 1)) conbox = wx.StaticBoxSizer( wx.StaticBox(self, wx.ID_ANY, "Continuous Scans"), wx.VERTICAL) conbox.Add(congrid, 0, wx.ALL | wx.EXPAND, 10) plotgrid = wx.GridBagSizer(10, 10) plotgrid.Add(textWidth, pos=(0, 0)) plotgrid.Add(self.ctrlWidth, pos=(0, 1)) plotbox = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Plot View"), wx.HORIZONTAL) plotbox.Add(plotgrid, 0, wx.ALL | wx.EXPAND, 10) grid = wx.GridBagSizer(10, 10) grid.Add(genbox, pos=(0, 0), span=(1, 2), flag=wx.EXPAND) grid.Add(conbox, pos=(1, 0), span=(1, 2), flag=wx.EXPAND) grid.Add(plotbox, pos=(2, 0), span=(1, 2), flag=wx.EXPAND) grid.Add(sizerButtons, pos=(3, 1), flag=wx.EXPAND) box = wx.BoxSizer() box.Add(grid, flag=wx.ALL | wx.ALIGN_CENTRE, border=10) self.SetSizerAndFit(box) def __on_alert(self, _event): enabled = self.checkAlert.GetValue() self.spinLevel.Enable(enabled) def __on_points(self, _event): enabled = self.checkPoints.GetValue() self.spinPoints.Enable(enabled) def __on_background(self, _event): colour = wx.ColourData() colour.SetColour(self.background) dlg = CubeColourDialog(self, colour, 0) if dlg.ShowModal() == wx.ID_OK: newColour = dlg.GetColourData().GetColour() self.background = newColour.GetAsString(wx.C2S_HTML_SYNTAX) self.buttonBackground.SetBackgroundColour(self.background) dlg.Destroy() def __on_radio(self, _event): enabled = self.radioRetain.GetValue() self.spinCtrlMaxScans.Enable(enabled) def __on_choice(self, _event): self.colourBar.set_map(self.choiceColour.GetStringSelection()) self.choiceColour.SetFocus() def __on_ok(self, _event): self.settings.saveWarn = self.checkSaved.GetValue() self.settings.backup = self.checkBackup.GetValue() self.settings.alert = self.checkAlert.GetValue() self.settings.alertLevel = self.spinLevel.GetValue() self.settings.clickTune = self.checkTune.GetValue() self.settings.pointsLimit = self.checkPoints.GetValue() self.settings.pointsMax = self.spinPoints.GetValue() self.settings.exportDpi = self.spinDpi.GetValue() self.settings.retainScans = self.radioRetain.GetValue() self.settings.lineWidth = self.ctrlWidth.GetValue() self.settings.retainMax = self.spinCtrlMaxScans.GetValue() self.settings.colourMap = self.choiceColour.GetStringSelection() self.settings.background = self.background self.EndModal(wx.ID_OK)