Beispiel #1
0
 def draw_cie(self):
     """ CIE 1931 2° xy plot """
     self.canvas.SetEnableLegend(True)
     self.canvas.proportional = True
     gfx = []
     # Add a few points at the extremes to define a bounding box
     gfx.append(
         plot.PolyLine([(0, -0.025), (1, 1)], colour=wx.Colour(0, 0, 0, 0)))
     # Add CIE 1931 outline
     gfx.append(
         plot.PolySpline(colormath.cie1931_2_xy,
                         colour=wx.Colour(102, 102, 102, 153),
                         width=1.75))
     gfx.append(
         plot.PolyLine(
             [colormath.cie1931_2_xy[0], colormath.cie1931_2_xy[-1]],
             colour=wx.Colour(102, 102, 102, 153),
             width=1.75))
     # Add comparison gamuts
     for rgb_space, pen_style in [("Rec. 2020", wx.SOLID),
                                  ("Adobe RGB (1998)", wx.SHORT_DASH),
                                  ("DCI P3", wx.DOT_DASH),
                                  ("Rec. 709", wx.DOT)]:
         values = []
         for R, G, B in [(1, 0, 0), (0, 1, 0), (0, 0, 1)]:
             values.append(colormath.RGB2xyY(R, G, B, rgb_space)[:2])
         values.append(values[0])
         gfx.append(
             plot.PolyLine(values,
                           colour=wx.Colour(102, 102, 102, 255),
                           legend=rgb_space.replace(" (1998)", ""),
                           width=2,
                           style=pen_style))
     # Add points
     for i, (XYZ, values, attrs) in enumerate(self.samples):
         if len(XYZ) != 3:
             continue
         xy = colormath.XYZ2xyY(*XYZ)[:2]
         gfx.append(
             plot.PolyMarker(
                 [colormath.XYZ2xyY(*XYZ)[:2]],
                 colour=wx.Colour(*self.gfx[i].attributes["colour"]),
                 size=2,
                 width=1.75,
                 marker="plus",
                 legend="%.4f\u2009x\u2002%.4f\u2009y" % xy))
     self.canvas.axis_x = 0, 1
     self.canvas.axis_y = 0, 1
     self.canvas.spec_x = 10
     self.canvas.spec_y = 10
     self.canvas.SetXSpec(10)
     self.canvas.SetYSpec(10)
     self.draw(gfx, " ", "x", "y")
 def show_RGB(self, clear_XYZ=True, mark_current_row=True):
     row = self.cgats[0].DATA[self.index]
     self.label_RGB.SetLabel(
         "RGB %i %i %i" % (round(
             row["RGB_R"] / 100.0 * 255), round(row["RGB_G"] / 100.0 * 255),
                           round(row["RGB_B"] / 100.0 * 255)))
     color = [
         int(round(v / 100.0 * 255))
         for v in (row["RGB_R"], row["RGB_G"], row["RGB_B"])
     ]
     self.panel_RGB.SetBackgroundColour(wx.Colour(*color))
     self.panel_RGB.SetBitmap(None)
     self.panel_RGB.Refresh()
     self.panel_RGB.Update()
     if clear_XYZ:
         self.label_XYZ.SetLabel(" ")
         self.panel_XYZ.SetBackgroundColour(BGCOLOUR)
         self.panel_XYZ.SetBitmap(
             getbitmap("theme/checkerboard-32x32x5-333-444"))
         self.panel_XYZ.Refresh()
         self.panel_XYZ.Update()
     if mark_current_row:
         self.grid.SetRowLabelValue(self.index,
                                    "\u25ba %i" % (self.index + 1))
         self.grid.MakeCellVisible(self.index, 0)
     if self.index not in self.grid.GetSelectedRows():
         self.grid.SelectRow(self.index)
         self.grid.SetGridCursor(self.index, 0)
     self.label_index.SetLabel("%i/%i" %
                               (self.index + 1, len(self.cgats[0].DATA)))
     self.label_index.GetContainingSizer().Layout()
 def show_XYZ(self):
     Lab, color = self.get_Lab_RGB()
     self.label_XYZ.SetLabel("L*a*b* %.2f %.2f %.2f" % Lab)
     self.panel_XYZ.SetBackgroundColour(wx.Colour(*color))
     self.panel_XYZ.SetBitmap(None)
     self.panel_XYZ.Refresh()
     self.panel_XYZ.Update()
Beispiel #4
0
    def __init__(self, parent, cgats, worker=None):
        """
		Init new CCXPlot window.

		parent   Parent window (only used for error dialogs)
		cgats    A CCMX/CCSS CGATS instance
		worker   Worker instance
		
		"""

        self.is_ccss = cgats[0].type == "CCSS"

        desc = cgats.get_descriptor()

        if cgats.filename:
            fn, ext = os.path.splitext(os.path.basename(cgats.filename))
        else:
            fn = desc
            if self.is_ccss:
                ext = ".ccss"
            else:
                ext = ".ccmx"

        desc = lang.getstr(ext[1:] + "." + fn, default=desc)

        if self.is_ccss:
            ccxx_type = "spectral"
        else:
            ccxx_type = "matrix"

        title = "%s: %s" % (lang.getstr(ccxx_type), desc)

        if self.is_ccss:
            # Convert to TI3 so we can get XYZ from spectra for coloring

            temp = worker.create_tempdir()
            if isinstance(temp, Exception):
                show_result_dialog(temp, parent)
            else:
                basename = make_filename_safe(desc)
                temp_path = os.path.join(temp, basename + ".ti3")

                cgats[0].type = "CTI3"
                cgats[0].DEVICE_CLASS = "DISPLAY"
                cgats.write(temp_path)

                temp_out_path = os.path.join(temp, basename + ".CIE.ti3")

                result = worker.exec_cmd(get_argyll_util("spec2cie"),
                                         [temp_path, temp_out_path],
                                         capture_output=True)
                if isinstance(result, Exception) or not result:
                    show_result_dialog(
                        UnloggedError(result or "".join(worker.errors)),
                        parent)
                    worker.wrapup(False)
                else:
                    try:
                        cgats = CGATS.CGATS(temp_out_path)
                    except Exception as exception:
                        show_result_dialog(exception, parent)
                    finally:
                        worker.wrapup(False)

        data_format = cgats.queryv1("DATA_FORMAT")
        data = cgats.queryv1("DATA")

        XYZ_max = 0
        self.samples = []

        if self.is_ccss:
            x_min = cgats.queryv1("SPECTRAL_START_NM")
            x_max = cgats.queryv1("SPECTRAL_END_NM")
            bands = cgats.queryv1("SPECTRAL_BANDS")
            lores = bands <= 40
            if lores:
                # Interpolate if lores
                # 1nm intervals
                steps = int(x_max - x_min) + 1
                safe_print("Up-interpolating", bands, "spectral bands to",
                           steps)
                step = (x_max - x_min) / (steps - 1.)
            else:
                step = (x_max - x_min) / (bands - 1.)
            y_min = 0
            y_max = 1

            Y_max = 0
            for i, sample in data.items():
                # Get nm and spectral power
                values = []
                x = x_min
                for k in data_format.values():
                    if k.startswith("SPEC_"):
                        y = sample[k]
                        y_min = min(y, y_min)
                        y_max = max(y, y_max)
                        if lores:
                            values.append(y)
                        else:
                            values.append((x, y))
                            x += step
                if lores:
                    # Interpolate if lores. Use Catmull-Rom instead of
                    # PolySpline as we want curves to go through points exactly
                    numvalues = len(values)
                    interp = ICCP.CRInterpolation(values)
                    values = []
                    for i in range(steps):
                        values.append(
                            (x, interp(i / (steps - 1.) * (numvalues - 1.))))
                        x += step
                # Get XYZ for colorization
                XYZ = []
                for component in "XYZ":
                    label = "XYZ_" + component
                    if label in sample:
                        v = sample[label]
                        XYZ_max = max(XYZ_max, v)
                        if label == "XYZ_Y":
                            Y_max = max(Y_max, v)
                        XYZ.append(v)
                self.samples.append((XYZ, values, {}))

            Plot = plot.PolyLine
            Plot._attributes["width"] = 1
        else:
            # CCMX
            cube_size = 2

            x_min = 0

            y_min = 0

            mtx = colormath.Matrix3x3(
                [[sample[k] for k in data_format.values()]
                 for sample in data.values()])
            imtx = mtx.inverted()

            # Get XYZ that colorimeter would measure without matrix (sRGB ref,
            # so not accurate, but useful for visual representation which is all
            # we care about here)
            if cube_size == 2:
                scale = 1
                x_max = 100 * scale
                y_max = x_max * (74.6 / 67.4)
                if sys.platform != "win32":
                    x_center = x_max / 2.
                else:
                    x_center = x_max / 2. - 2.5
                y_center = y_max / 2.
                x_center *= scale
                y_center *= scale
                pos2rgb = [((x_center - 23.7, y_center - 13.7), (0, 0, 1)),
                           ((x_center, y_center + 27.3), (0, 1, 0)),
                           ((x_center + 23.7, y_center - 13.7), (1, 0, 0)),
                           ((x_center - 23.7, y_center + 13.7), (0, 1, 1)),
                           ((x_center, y_center - 27.3), (1, 0, 1)),
                           ((x_center + 23.7, y_center + 13.7), (1, 1, 0)),
                           ((x_center, y_center), (1, 1, 1))]
                attrs_c = {'size': 10}
                attrs_r = {'size': 5}
            else:
                x_max = 100
                y_max = 100
                y = -5
                pos2rgb = []
                for R in range(cube_size):
                    for G in range(cube_size):
                        x = -5
                        y += 10
                        for B in range(cube_size):
                            x += 10
                            pos2rgb.append(((x, y), (v / (cube_size - 1.0)
                                                     for v in (R, G, B))))
                attrs_c = {'marker': 'square', 'size': 10}
                attrs_r = {'marker': 'square', 'size': 5}
            Y_max = (imtx * colormath.get_whitepoint("D65"))[1]
            for i, ((x, y), (R, G, B)) in enumerate(pos2rgb):
                XYZ = list(colormath.RGB2XYZ(R, G, B))
                X, Y, Z = imtx * XYZ
                XYZ_max = max(XYZ_max, X, Y, Z)
                self.samples.append(([X, Y, Z], [(x, y)], attrs_c))
                self.samples.append((XYZ, [(x, y)], attrs_r))

            Plot = plot.PolyMarker

        if self.is_ccss:
            # Protect against division by zero when range is zero
            if not x_max - x_min:
                x_min = 350.0
                x_max = 750.0
            if not y_max - y_min:
                y_min = 0.0
                y_max = 10.0

            y_zero = 0

            self.ccxx_axis_x = (math.floor(x_min / 50.) * 50,
                                math.ceil(x_max / 50.) * 50)
            self.spec_x = (self.ccxx_axis_x[1] - self.ccxx_axis_x[0]) / 50.
            graph_range = nicenum(y_max - y_zero, False)
            d = nicenum(graph_range / (NTICK - 1.0), True)
            self.spec_y = math.ceil(y_max / d)
            self.ccxx_axis_y = (math.floor(y_zero / d) * d, self.spec_y * d)
        else:
            self.ccxx_axis_x = (math.floor(x_min / 20.) * 20,
                                math.ceil(x_max / 20.) * 20)
            self.ccxx_axis_y = (math.floor(y_min), math.ceil(y_max))

        self.gfx = []
        for XYZ, values, attrs in self.samples:
            if len(XYZ) == 3:
                # Got XYZ
                if attrs.get("size") > 11.25:
                    # Colorimeter XYZ
                    if Y_max > 1:
                        # Colorimeter brighter than ref
                        XYZ[:] = [v / Y_max for v in XYZ]
                    else:
                        # Colorimeter dimmer than ref
                        XYZ[:] = [v * Y_max for v in XYZ]
                else:
                    # Ref XYZ
                    if Y_max > 1:
                        # Colorimeter brighter than ref
                        XYZ[:] = [v / Y_max for v in XYZ]
                RGB = tuple(
                    int(v)
                    for v in colormath.XYZ2RGB(*XYZ, scale=255, round_=True))
            else:
                RGB = (153, 153, 153)
            self.gfx.append(Plot(values, colour=wx.Colour(*RGB), **attrs))
        if self.is_ccss:
            # Add a few points at the extremes to define a bounding box
            self.gfx.append(
                plot.PolyLine(
                    [(self.ccxx_axis_x[0], self.ccxx_axis_y[0]),
                     (self.ccxx_axis_x[1], self.ccxx_axis_y[1] - y_min)],
                    colour=wx.Colour(0, 0, 0, 0)))

        ref = cgats.queryv1("REFERENCE")
        if ref:
            ref = get_canonical_instrument_name(safe_unicode(ref, "UTF-8"))

        if not self.is_ccss:
            observers_ab = {}
            for observer in config.valid_values["observer"]:
                observers_ab[observer] = lang.getstr("observer." + observer)
            x_label = [lang.getstr("matrix")]
            x_label.extend(["%9.6f %9.6f %9.6f" % tuple(row) for row in mtx])
            if ref:
                ref_observer = cgats.queryv1("REFERENCE_OBSERVER")
                if ref_observer:
                    ref += ", " + observers_ab.get(ref_observer, ref_observer)
                x_label.append("")
                x_label.append(ref)
            fit_method = cgats.queryv1("FIT_METHOD")
            if fit_method == "xy":
                fit_method = lang.getstr("ccmx.use_four_color_matrix_method")
            elif fit_method:
                fit_method = lang.getstr("perceptual")
            fit_de00_avg = cgats.queryv1("FIT_AVG_DE00")
            if not isinstance(fit_de00_avg, float):
                fit_de00_avg = None
            fit_de00_max = cgats.queryv1("FIT_MAX_DE00")
            if not isinstance(fit_de00_max, float):
                fit_de00_max = None
            if fit_method:
                x_label.append(fit_method)
            fit_de00 = []
            if fit_de00_avg:
                fit_de00.append(
                    "ΔE*00 %s %.4f" %
                    (lang.getstr("profile.self_check.avg"), fit_de00_avg))
            if fit_de00_max:
                fit_de00.append(
                    "ΔE*00 %s %.4f" %
                    (lang.getstr("profile.self_check.max"), fit_de00_max))
            if fit_de00:
                x_label.append("\n".join(fit_de00))
            x_label = "\n".join(x_label)
        else:
            x_label = ""
            if ref:
                x_label += ref + ", "
            x_label += "%.1fnm, %i-%inm" % ((x_max - x_min) /
                                            (bands - 1.0), x_min, x_max)

        scale = max(getcfg("app.dpi") / config.get_default_dpi(), 1)

        style = wx.DEFAULT_FRAME_STYLE

        wx.Frame.__init__(self, None, -1, title, style=style)
        self.SetIcons(config.get_icon_bundle([256, 48, 32, 16], appname))
        self.SetBackgroundColour(BGCOLOUR)
        self.Sizer = wx.GridSizer(1, 1, 0, 0)
        bg = wx.Panel(self)
        bg.SetBackgroundColour(BGCOLOUR)
        bg.Sizer = wx.BoxSizer(wx.VERTICAL)
        self.canvas = canvas = LUTCanvas(bg)
        if self.is_ccss:
            bg.MinSize = (513 * scale, 557 * scale)
            btnsizer = wx.BoxSizer(wx.HORIZONTAL)
            bg.Sizer.Add(btnsizer,
                         flag=wx.EXPAND | wx.TOP | wx.RIGHT | wx.LEFT,
                         border=16)
            self.toggle_btn = FlatShadedButton(bg,
                                               -1,
                                               label=lang.getstr("spectral"))
            btnsizer.Add(self.toggle_btn, 1)
            self.Sizer.Add(bg, 1, flag=wx.EXPAND)
            bg.Sizer.Add(canvas, 1, flag=wx.EXPAND)
        else:
            self.Sizer.Add(bg, flag=wx.ALIGN_CENTER)
            canvas_w = 240 * scale
            canvas.MinSize = (canvas_w, canvas_w * (74.6 / 67.4))
            bg.Sizer.Add(canvas, flag=wx.ALIGN_CENTER)
        label = wx.StaticText(bg,
                              -1,
                              x_label.replace("&", "&&"),
                              style=wx.ALIGN_CENTRE_HORIZONTAL)
        label.SetForegroundColour(FGCOLOUR)
        label.SetMaxFontSize(11)
        bg.Sizer.Add(label,
                     flag=wx.ALIGN_CENTER | wx.ALL & ~wx.TOP,
                     border=16 * scale)
        canvas.SetBackgroundColour(BGCOLOUR)
        canvas.SetEnableCenterLines(False)
        canvas.SetEnableDiagonals(False)
        canvas.SetEnableGrid(True)
        canvas.enableTicks = (True, True)
        canvas.tickPen = wx.Pen(GRIDCOLOUR, canvas._pointSize[0])
        canvas.SetEnablePointLabel(False)
        canvas.SetEnableTitle(True)
        canvas.SetForegroundColour(FGCOLOUR)
        canvas.SetGridColour(GRIDCOLOUR)
        canvas.canvas.BackgroundColour = BGCOLOUR
        if self.is_ccss:
            canvas.HandCursor = wx.StockCursor(wx.CURSOR_SIZING)
            canvas.SetCursor(canvas.HandCursor)
        else:
            canvas.canvas.Unbind(wx.EVT_LEFT_DCLICK)
            canvas.SetEnableDrag(False)
            canvas.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
            canvas.SetXSpec('none')
            canvas.SetYSpec('none')

        # CallAfter is needed under GTK as usual
        wx.CallAfter(self.draw_ccxx)

        if self.is_ccss:
            self.Bind(wx.EVT_KEY_DOWN, self.key_handler)
            for child in self.GetAllChildren():
                child.Bind(wx.EVT_KEY_DOWN, self.key_handler)
                child.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel)

            self.toggle_btn.Bind(wx.EVT_BUTTON, self.toggle_draw)

            self.Bind(wx.EVT_SIZE, self.OnSize)
        else:
            bg.Sizer.Add((0, 16))
        self.Sizer.SetSizeHints(self)
        self.Sizer.Layout()
 def parse_txt(self, txt):
     if not txt:
         return
     self.logger.info("%r" % txt)
     data_len = len(self.cgats[0].DATA)
     if (self.grid.GetNumberRows() < data_len):
         self.index = 0
         self.index_max = data_len - 1
         self.grid.AppendRows(data_len - self.grid.GetNumberRows())
         for i in self.cgats[0].DATA:
             self.grid.SetRowLabelValue(i, "%i" % (i + 1))
             row = self.cgats[0].DATA[i]
             RGB = []
             for j, label in enumerate("RGB"):
                 value = int(round(row["RGB_%s" % label] / 100.0 * 255))
                 self.grid.SetCellValue(row.SAMPLE_ID - 1, j, "%i" % value)
                 RGB.append(value)
             self.grid.SetCellBackgroundColour(row.SAMPLE_ID - 1, 3,
                                               wx.Colour(*RGB))
     if "Connecting to the instrument" in txt:
         self.Pulse(lang.getstr("instrument.initializing"))
     if "Spot read needs a calibration" in txt:
         self.is_measuring = False
     if "Spot read failed" in txt:
         self.last_error = txt
     if "Result is XYZ:" in txt:
         self.last_error = None
         if getcfg("measurement.play_sound"):
             self.measurement_sound.safe_play()
         # Result is XYZ: d.dddddd d.dddddd d.dddddd, D50 Lab: d.dddddd d.dddddd d.dddddd
         XYZ = re.search(
             "XYZ:\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)",
             txt)
         if not XYZ:
             return
         XYZ = [float(v) for v in XYZ.groups()]
         row = self.cgats[0].DATA[self.index]
         if (row["RGB_R"] == 100 and row["RGB_G"] == 100
                 and row["RGB_B"] == 100):
             # White
             if XYZ[1] > 0:
                 self.cgats[0].add_keyword("LUMINANCE_XYZ_CDM2",
                                           "%.6f %.6f %.6f" % tuple(XYZ))
                 self.white_XYZ = XYZ
         Lab1 = colormath.XYZ2Lab(*self.last_XYZ)
         Lab2 = colormath.XYZ2Lab(*XYZ)
         delta = colormath.delta(*Lab1 + Lab2)
         if debug or test or verbose > 1:
             safe_print("Last recorded Lab: %.4f %.4f %.4f" % Lab1)
             safe_print("Current Lab: %.4f %.4f %.4f" % Lab2)
             safe_print("Delta E to last recorded Lab: %.4f" % delta["E"])
             safe_print("Abs. delta L to last recorded Lab: %.4f" %
                        abs(delta["L"]))
             safe_print("Abs. delta C to last recorded Lab: %.4f" %
                        abs(delta["C"]))
         if (delta["E"] > getcfg("untethered.min_delta") or
             (abs(delta["L"]) > getcfg("untethered.min_delta.lightness")
              and abs(delta["C"]) < getcfg("untethered.max_delta.chroma"))):
             self.measure_count += 1
             if self.measure_count == 2:
                 if getcfg("measurement.play_sound"):
                     self.commit_sound.safe_play()
                 self.measure_count = 0
                 # Reset row label
                 self.grid.SetRowLabelValue(self.index,
                                            "%i" % (self.index + 1))
                 # Update CGATS
                 query = self.cgats[0].queryi({
                     "RGB_R": row["RGB_R"],
                     "RGB_G": row["RGB_G"],
                     "RGB_B": row["RGB_B"]
                 })
                 for i in query:
                     index = query[i].SAMPLE_ID - 1
                     if index not in self.measured:
                         self.measured.append(index)
                     if index == self.index + 1:
                         # Increment the index if we have consecutive patches
                         self.index = index
                     query[i]["XYZ_X"], query[i]["XYZ_Y"], query[i][
                         "XYZ_Z"] = XYZ
                 if getcfg("untethered.measure.auto"):
                     self.show_RGB(False, False)
                 self.show_XYZ()
                 Lab, color = self.get_Lab_RGB()
                 for i in query:
                     row = query[i]
                     self.grid.SetCellBackgroundColour(
                         query[i].SAMPLE_ID - 1, 4, wx.Colour(*color))
                     for j in range(3):
                         self.grid.SetCellValue(query[i].SAMPLE_ID - 1,
                                                5 + j, "%.2f" % Lab[j])
                 self.grid.MakeCellVisible(self.index, 0)
                 self.grid.ForceRefresh()
                 if len(self.measured) == data_len:
                     self.finished = True
                     self.finish_btn.Enable()
                 else:
                     # Jump to the next or previous unmeasured patch, if any
                     index = self.index
                     for i in range(self.index + 1, data_len):
                         if (getcfg("untethered.measure.auto")
                                 or not i in self.measured):
                             self.index = i
                             break
                     if self.index == index:
                         for i in range(self.index - 1, -1, -1):
                             if not i in self.measured:
                                 self.index = i
                                 break
                     if self.index != index:
                         # Mark the row containing the next/previous patch
                         self.grid.SetRowLabelValue(
                             self.index, "\u25ba %i" % (self.index + 1))
                         self.grid.MakeCellVisible(self.index, 0)
     if "key to take a reading" in txt and not self.last_error:
         if getcfg("untethered.measure.auto") and self.is_measuring:
             if not self.finished and self.keepGoing:
                 self.measure()
             else:
                 self.enable_btns()
         else:
             show_XYZ = self.index in self.measured
             delay = getcfg("untethered.measure.manual.delay") * 1000
             wx.CallLater(delay, self.show_RGB, not show_XYZ)
             if show_XYZ:
                 wx.CallLater(delay, self.show_XYZ)
             wx.CallLater(delay, self.enable_btns)
    def __init__(self,
                 parent=None,
                 handler=None,
                 keyhandler=None,
                 start_timer=True):
        BaseFrame.__init__(self,
                           parent,
                           wx.ID_ANY,
                           lang.getstr("measurement.untethered"),
                           style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
                           name="untetheredframe")
        self.SetIcons(get_icon_bundle([256, 48, 32, 16], appname))
        self.sizer = wx.FlexGridSizer(2, 1, 0, 0)
        self.sizer.AddGrowableCol(0)
        self.sizer.AddGrowableRow(0)
        self.sizer.AddGrowableRow(1)
        self.panel = wx_Panel(self)
        self.SetSizer(self.sizer)
        self.sizer.Add(self.panel, 1, wx.EXPAND)
        self.panel.SetBackgroundColour(BGCOLOUR)
        panelsizer = wx.FlexGridSizer(3, 2, 8, 8)
        panelsizer.AddGrowableCol(0)
        panelsizer.AddGrowableCol(1)
        panelsizer.AddGrowableRow(1)
        self.panel.SetSizer(panelsizer)
        self.label_RGB = wx.StaticText(self.panel, wx.ID_ANY, " ")
        self.label_RGB.SetForegroundColour(FGCOLOUR)
        panelsizer.Add(self.label_RGB,
                       0,
                       wx.TOP | wx.LEFT | wx.EXPAND,
                       border=8)
        self.label_XYZ = wx.StaticText(self.panel, wx.ID_ANY, " ")
        self.label_XYZ.SetForegroundColour(FGCOLOUR)
        panelsizer.Add(self.label_XYZ,
                       0,
                       wx.TOP | wx.RIGHT | wx.EXPAND,
                       border=8)
        if sys.platform == "darwin":
            style = wx.BORDER_THEME
        else:
            style = wx.BORDER_SIMPLE
        self.panel_RGB = BitmapBackgroundPanel(self.panel,
                                               size=(256, 256),
                                               style=style)
        self.panel_RGB.scalebitmap = (True, True)
        self.panel_RGB.SetBitmap(
            getbitmap("theme/checkerboard-32x32x5-333-444"))
        panelsizer.Add(self.panel_RGB, 1, wx.LEFT | wx.EXPAND, border=8)
        self.panel_XYZ = BitmapBackgroundPanel(self.panel,
                                               size=(256, 256),
                                               style=style)
        self.panel_XYZ.scalebitmap = (True, True)
        self.panel_XYZ.SetBitmap(
            getbitmap("theme/checkerboard-32x32x5-333-444"))
        panelsizer.Add(self.panel_XYZ, 1, wx.RIGHT | wx.EXPAND, border=8)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.back_btn = FlatShadedButton(self.panel,
                                         bitmap=geticon(10, "back"),
                                         label="",
                                         fgcolour=FGCOLOUR)
        self.back_btn.Bind(wx.EVT_BUTTON, self.back_btn_handler)
        sizer.Add(self.back_btn, 0, wx.LEFT | wx.RIGHT, border=8)
        self.label_index = wx.StaticText(self.panel, wx.ID_ANY, " ")
        self.label_index.SetForegroundColour(FGCOLOUR)
        sizer.Add(self.label_index, 0, wx.ALIGN_CENTER_VERTICAL)
        self.next_btn = FlatShadedButton(self.panel,
                                         bitmap=geticon(10, "play"),
                                         label="",
                                         fgcolour=FGCOLOUR)
        self.next_btn.Bind(wx.EVT_BUTTON, self.next_btn_handler)
        sizer.Add(self.next_btn, 0, wx.LEFT, border=8)
        sizer.Add((12, 1), 1)
        self.measure_auto_cb = CustomCheckBox(self.panel, wx.ID_ANY,
                                              lang.getstr("auto"))
        self.measure_auto_cb.SetForegroundColour(FGCOLOUR)
        self.measure_auto_cb.Bind(wx.EVT_CHECKBOX,
                                  self.measure_auto_ctrl_handler)
        sizer.Add(self.measure_auto_cb, 0,
                  wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
        panelsizer.Add(sizer, 0, wx.BOTTOM | wx.EXPAND, border=8)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.measure_btn = FlatShadedButton(self.panel,
                                            bitmap=geticon(10, "play"),
                                            label=lang.getstr("measure"),
                                            fgcolour=FGCOLOUR)
        self.measure_btn.Bind(wx.EVT_BUTTON, self.measure_btn_handler)
        sizer.Add(self.measure_btn, 0, wx.RIGHT, border=6)
        # Sound when measuring
        # Needs to be stereo!
        self.measurement_sound = audio.Sound(get_data_path("beep.wav"))
        self.commit_sound = audio.Sound(get_data_path("camera_shutter.wav"))
        bitmap = self.get_sound_on_off_btn_bitmap()
        self.sound_on_off_btn = FlatShadedButton(self.panel,
                                                 bitmap=bitmap,
                                                 fgcolour=FGCOLOUR)
        self.sound_on_off_btn.SetToolTipString(
            lang.getstr("measurement.play_sound"))
        self.sound_on_off_btn.Bind(wx.EVT_BUTTON,
                                   self.measurement_play_sound_handler)
        sizer.Add(self.sound_on_off_btn, 0)
        sizer.Add((12, 1), 1)
        self.finish_btn = FlatShadedButton(self.panel,
                                           label=lang.getstr("finish"),
                                           fgcolour=FGCOLOUR)
        self.finish_btn.Bind(wx.EVT_BUTTON, self.finish_btn_handler)
        sizer.Add(self.finish_btn, 0, wx.RIGHT, border=8)
        panelsizer.Add(sizer, 0, wx.BOTTOM | wx.EXPAND, border=8)

        self.grid = CustomGrid(self, -1, size=(536, 256))
        self.grid.DisableDragColSize()
        self.grid.DisableDragRowSize()
        self.grid.SetScrollRate(0, 5)
        self.grid.SetCellHighlightROPenWidth(0)
        self.grid.SetColLabelSize(self.grid.GetDefaultRowSize())
        self.grid.SetDefaultCellAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
        self.grid.SetRowLabelAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTER)
        self.grid.draw_horizontal_grid_lines = False
        self.grid.draw_vertical_grid_lines = False
        self.grid.style = ""
        self.grid.CreateGrid(0, 9)
        self.grid.SetRowLabelSize(62)
        for i in range(9):
            if i in (3, 4):
                size = self.grid.GetDefaultRowSize()
                if i == 4:
                    attr = wx.grid.GridCellAttr()
                    attr.SetBackgroundColour(wx.Colour(0, 0, 0, 0))
                    self.grid.SetColAttr(i, attr)
            else:
                size = 62
            self.grid.SetColSize(i, size)
        for i, label in enumerate(
            ["R", "G", "B", "", "", "L*", "a*", "b*", ""]):
            self.grid.SetColLabelValue(i, label)
        self.grid.SetCellHighlightPenWidth(0)
        self.grid.SetDefaultCellBackgroundColour(
            self.grid.GetLabelBackgroundColour())
        font = self.grid.GetDefaultCellFont()
        if font.PointSize > 11:
            font.PointSize = 11
            self.grid.SetDefaultCellFont(font)
        self.grid.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
        self.grid.EnableEditing(False)
        self.grid.EnableGridLines(False)
        self.grid.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK,
                       self.grid_left_click_handler)
        self.grid.Bind(wx.grid.EVT_GRID_SELECT_CELL,
                       self.grid_left_click_handler)
        self.sizer.Add(self.grid, 1, wx.EXPAND)

        self.Fit()
        self.SetMinSize(self.GetSize())

        self.keyhandler = keyhandler
        self.id_to_keycode = {}
        if sys.platform == "darwin":
            # Use an accelerator table for tab, space, 0-9, A-Z, numpad,
            # navigation keys and processing keys
            keycodes = [wx.WXK_TAB, wx.WXK_SPACE]
            keycodes.extend(list(range(ord("0"), ord("9"))))
            keycodes.extend(list(range(ord("A"), ord("Z"))))
            keycodes.extend(numpad_keycodes)
            keycodes.extend(nav_keycodes)
            keycodes.extend(processing_keycodes)
            for keycode in keycodes:
                self.id_to_keycode[wx.Window.NewControlId()] = keycode
            accels = []
            for id, keycode in self.id_to_keycode.items():
                self.Bind(wx.EVT_MENU, self.key_handler, id=id)
                accels.append((wx.ACCEL_NORMAL, keycode, id))
                if keycode == wx.WXK_TAB:
                    accels.append((wx.ACCEL_SHIFT, keycode, id))
            self.SetAcceleratorTable(wx.AcceleratorTable(accels))
        else:
            self.Bind(wx.EVT_CHAR_HOOK, self.key_handler)

        self.Bind(wx.EVT_KEY_DOWN, self.key_handler)

        # Event handlers
        self.Bind(wx.EVT_CLOSE, self.OnClose, self)
        self.Bind(wx.EVT_MOVE, self.OnMove, self)
        self.Bind(wx.EVT_SIZE, self.OnResize, self)
        self.timer = wx.Timer(self)
        if handler:
            self.Bind(wx.EVT_TIMER, handler, self.timer)
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy, self)

        # Final initialization steps
        for child in self.GetAllChildren():
            if (sys.platform == "win32" and sys.getwindowsversion() >= (6, )
                    and isinstance(child, wx.Panel)):
                # No need to enable double buffering under Linux and Mac OS X.
                # Under Windows, enabling double buffering on the panel seems
                # to work best to reduce flicker.
                child.SetDoubleBuffered(True)
        self.logger = get_file_logger("untethered")
        self._setup()

        self.Show()

        if start_timer:
            self.start_timer()
from config import (getbitmap, getcfg, geticon, get_data_path, get_icon_bundle,
                    setcfg)
from log import get_file_logger, safe_print
from meta import name as appname
from options import debug, test, verbose
from wxwindows import (BaseApp, BaseFrame, BitmapBackgroundPanel,
                       CustomCheckBox, CustomGrid, FlatShadedButton,
                       numpad_keycodes, nav_keycodes, processing_keycodes,
                       wx_Panel)
import CGATS
import audio
import colormath
import config
import localization as lang

BGCOLOUR = wx.Colour(0x33, 0x33, 0x33)
FGCOLOUR = wx.Colour(0x99, 0x99, 0x99)


class UntetheredFrame(BaseFrame):
    def __init__(self,
                 parent=None,
                 handler=None,
                 keyhandler=None,
                 start_timer=True):
        BaseFrame.__init__(self,
                           parent,
                           wx.ID_ANY,
                           lang.getstr("measurement.untethered"),
                           style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
                           name="untetheredframe")
Beispiel #8
0
    def __init__(self,
                 parent=None,
                 handler=None,
                 keyhandler=None,
                 start_timer=True,
                 rows=None,
                 cols=None):
        if not rows:
            rows = getcfg("uniformity.rows")
        if not cols:
            cols = getcfg("uniformity.cols")
        BaseFrame.__init__(self,
                           parent,
                           wx.ID_ANY,
                           lang.getstr("report.uniformity"),
                           style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
                           name="displayuniformityframe")
        self.SetIcons(get_icon_bundle([256, 48, 32, 16], appname))
        self.SetBackgroundColour(BGCOLOUR)
        self.sizer = wx.GridSizer(rows, cols, 0, 0)
        self.SetSizer(self.sizer)

        self.rows = rows
        self.cols = cols
        self.colors = (wx.WHITE, wx.Colour(192, 192, 192),
                       wx.Colour(128, 128, 128), wx.Colour(64, 64, 64))
        self.labels = {}
        self.panels = []
        self.buttons = []
        for index in range(rows * cols):
            panel = wx_Panel(self, style=wx.BORDER_SIMPLE)
            panel.SetBackgroundColour(BGCOLOUR)
            sizer = wx.BoxSizer(wx.VERTICAL)
            panel.SetSizer(sizer)
            self.panels.append(panel)
            button = FlatShadedNumberedButton(
                panel,
                label=lang.getstr("measure"),
                bitmap=getbitmap("theme/icons/10x10/record"),
                index=index)
            button.Bind(wx.EVT_BUTTON, self.measure)
            self.buttons.append(button)
            label = wx.StaticText(panel)
            label.SetForegroundColour(wx.WHITE)
            self.labels[index] = label
            sizer.Add(label, 1, wx.ALIGN_CENTER)
            sizer.Add(button,
                      0,
                      wx.ALIGN_BOTTOM | wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT
                      | wx.RIGHT,
                      border=8)
            self.sizer.Add(panel, 1, wx.EXPAND)
        self.disable_buttons()

        self.keyhandler = keyhandler
        self.id_to_keycode = {}
        if sys.platform == "darwin":
            # Use an accelerator table for tab, space, 0-9, A-Z, numpad,
            # navigation keys and processing keys
            keycodes = [wx.WXK_TAB, wx.WXK_SPACE]
            keycodes.extend(list(range(ord("0"), ord("9"))))
            keycodes.extend(list(range(ord("A"), ord("Z"))))
            keycodes.extend(numpad_keycodes)
            keycodes.extend(nav_keycodes)
            keycodes.extend(processing_keycodes)
            for keycode in keycodes:
                self.id_to_keycode[wx.Window.NewControlId()] = keycode
            accels = []
            for id, keycode in self.id_to_keycode.items():
                self.Bind(wx.EVT_MENU, self.key_handler, id=id)
                accels.append((wx.ACCEL_NORMAL, keycode, id))
                if keycode == wx.WXK_TAB:
                    accels.append((wx.ACCEL_SHIFT, keycode, id))
            self.SetAcceleratorTable(wx.AcceleratorTable(accels))
        else:
            self.Bind(wx.EVT_CHAR_HOOK, self.key_handler)

        # Event handlers
        self.Bind(wx.EVT_CLOSE, self.OnClose, self)
        self.Bind(wx.EVT_MOVE, self.OnMove, self)
        self.timer = wx.Timer(self)
        if handler:
            self.Bind(wx.EVT_TIMER, handler, self.timer)
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy, self)

        # Final initialization steps
        self.logger = get_file_logger("uniformity")
        self._setup()

        self.Show()

        if start_timer:
            self.start_timer()
Beispiel #9
0
from config import (getbitmap, getcfg, get_icon_bundle, get_display_number,
                    get_display_rects, get_verified_path, setcfg)
from log import get_file_logger, safe_print
from meta import name as appname, version as appversion
from util_os import launch_file, waccess
from wxaddons import CustomEvent
from wxMeasureFrame import MeasureFrame
from wxwindows import (BaseApp, BaseFrame, FlatShadedButton, numpad_keycodes,
                       nav_keycodes, processing_keycodes, wx_Panel)
import colormath
import config
import localization as lang
import report

BGCOLOUR = wx.Colour(0x33, 0x33, 0x33)


class FlatShadedNumberedButton(FlatShadedButton):
    def __init__(self,
                 parent,
                 id=wx.ID_ANY,
                 bitmap=None,
                 label="",
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.NO_BORDER,
                 validator=wx.DefaultValidator,
                 name="gradientbutton",
                 bgcolour=None,
                 fgcolour=None,