Exemplo n.º 1
0
    def __init__(self,
                 scene_canvas=None,
                 image=None,
                 input_colourspace='ITU-R BT.709',
                 correlate_colourspace='ACEScg',
                 diagram='CIE 1931',
                 **kwargs):
        self._initialised = False

        ViewBox.__init__(self, **kwargs)

        self.unfreeze()

        self._scene_canvas = scene_canvas

        self._image = None
        self.image = image
        self._input_colourspace = None
        self.input_colourspace = input_colourspace
        self._correlate_colourspace = None
        self.correlate_colourspace = correlate_colourspace
        self._diagram = None
        self.diagram = diagram

        self._diagrams_cycle = Cycle(CHROMATICITY_DIAGRAMS)

        self._grid = None

        self._label = None

        self._chromaticity_diagram_visual = None
        self._spectral_locus_visual = None
        self._RGB_scatter_visual = None
        self._input_colourspace_visual = None
        self._correlate_colourspace_visual = None
        self._pointer_gamut_visual = None
        self._pointer_gamut_boundaries_visual = None
        self._grid_visual = None
        self._axis_visual = None

        self._visuals = ('chromaticity_diagram_visual',
                          'spectral_locus_visual',
                          'RGB_scatter_visual',
                          'input_colourspace_visual',
                          'correlate_colourspace_visual',
                          'pointer_gamut_visual',
                          'pointer_gamut_boundaries_visual',
                          'grid_visual',
                          'axis_visual')

        self._visuals_visibility = None

        self._create_visuals()
        self._attach_visuals()
        self._create_camera()

        self._create_label()

        self._initialised = True
Exemplo n.º 2
0
    def _create_visuals_style_presets(self):
        """
        Creates the visuals style presets using :attr:`GamutView.settings`
        attribute value.
        """

        for visual, styles in self._settings['styles']['gamut_view'].items():
            self._visuals_style_presets[visual] = []

            for style in styles:
                if visual in ('input_colourspace_visual',
                              'correlate_colourspace_visual'):
                    self._visuals_style_presets[style['visual']].append(
                        RGB_ColourspaceVisualPreset(
                            name=style['name'],
                            description=style['description'],
                            segments=style['segments'],
                            uniform_colour=style['uniform_colour'],
                            uniform_opacity=style['uniform_opacity'],
                            wireframe=style['wireframe'],
                            wireframe_colour=style['wireframe_colour'],
                            wireframe_opacity=style['wireframe_opacity']))
                elif visual in 'grid_visual':
                    self._visuals_style_presets[style['visual']].append(
                        GridVisualPreset(
                            name=style['name'],
                            description=style['description'],
                            uniform_colour=style['uniform_colour']))

            self._visuals_style_presets[visual] = Cycle(
                self._visuals_style_presets[visual])
    def __init__(self,
                 scene_canvas=None,
                 image=None,
                 input_colourspace='ITU-R BT.709',
                 correlate_colourspace='ACEScg',
                 diagram='CIE 1931',
                 **kwargs):
        self._initialised = False

        ViewBox.__init__(self, **kwargs)

        self.unfreeze()

        self._scene_canvas = scene_canvas

        self._image = None
        self.image = image
        self._input_colourspace = None
        self.input_colourspace = input_colourspace
        self._correlate_colourspace = None
        self.correlate_colourspace = correlate_colourspace
        self._diagram = None
        self.diagram = diagram

        self._diagrams_cycle = Cycle(CHROMATICITY_DIAGRAMS)

        self._grid = None

        self._label = None

        self._chromaticity_diagram_visual = None
        self._spectral_locus_visual = None
        self._RGB_scatter_visual = None
        self._input_colourspace_visual = None
        self._correlate_colourspace_visual = None
        self._pointer_gamut_visual = None
        self._pointer_gamut_boundaries_visual = None
        self._grid_visual = None
        self._axis_visual = None

        self._visuals = ('chromaticity_diagram_visual',
                         'spectral_locus_visual', 'RGB_scatter_visual',
                         'input_colourspace_visual',
                         'correlate_colourspace_visual',
                         'pointer_gamut_visual',
                         'pointer_gamut_boundaries_visual', 'grid_visual',
                         'axis_visual')

        self._visuals_visibility = None

        self._create_visuals()
        self._attach_visuals()
        self._create_camera()

        self._create_label()

        self._initialised = True
Exemplo n.º 4
0
    def __init__(self,
                 canvas=None,
                 image=None,
                 input_colourspace='Rec. 709',
                 correlate_colourspace='ACEScg',
                 diagram='CIE 1931',
                 **kwargs):
        self.__initialised = False

        ViewBox.__init__(self, **kwargs)

        self.__canvas = canvas

        self.__image = None
        self.image = image
        self.__input_colourspace = None
        self.input_colourspace = input_colourspace
        self.__correlate_colourspace = None
        self.correlate_colourspace = correlate_colourspace
        self.__diagram = None
        self.diagram = diagram

        self.__diagrams_cycle = Cycle(CHROMATICITY_DIAGRAMS)

        self.__title_overlay_visual = None

        self.__chromaticity_diagram_visual = None
        self.__spectral_locus_visual = None
        self.__RGB_scatter_visual = None
        self.__input_colourspace_visual = None
        self.__correlate_colourspace_visual = None
        self.__pointer_gamut_visual = None
        self.__pointer_gamut_boundaries_visual = None
        self.__grid_visual = None
        self.__axis_visual = None

        self.__visuals = ('chromaticity_diagram_visual',
                          'spectral_locus_visual',
                          'RGB_scatter_visual',
                          'input_colourspace_visual',
                          'correlate_colourspace_visual',
                          'pointer_gamut_visual',
                          'pointer_gamut_boundaries_visual',
                          'grid_visual',
                          'axis_visual')

        self.__visuals_visibility = None

        self.__create_visuals()
        self.__attach_visuals()
        self.__create_camera()

        self.__create_title_overlay_visual()
        self.__canvas.events.resize.connect(self.__canvas_resize_event)

        self.__initialised = True
Exemplo n.º 5
0
class DiagramView(ViewBox):
    """
    Defines the *Diagram View*.

    Parameters
    ----------
    scene_canvas : SceneCanvas, optional
        Current `vispy.scene.SceneCanvas` instance.
    image : array_like, optional
        Image to use in the view interactions.
    input_colourspace : unicode, optional
        See `oecf` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the
        `image` argument colourspace.
    correlate_colourspace : unicode, optional
        See `oecf` argument for possible values, default value is *ACEScg*.

        :class:`colour.RGB_Colourspace` class instance name defining the
        comparison / correlate colourspace.
    diagram : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Chromaticity diagram to draw.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        Keywords arguments passed to
        :class:`vispy.scene.widgets.viewbox.Viewbox` class constructor.

    Attributes
    ----------
    scene_canvas
    image
    input_colourspace
    correlate_colourspace
    diagram

    Methods
    -------
    toggle_spectral_locus_visual_visibility_action
    toggle_input_colourspace_visual_visibility_action
    toggle_correlate_colourspace_visual_visibility_action
    toggle_RGB_scatter_visual_visibility_action
    toggle_pointer_gamut_visual_visibility_action
    toggle_grid_visual_visibility_action
    toggle_axis_visual_visibility_action
    cycle_chromaticity_diagram_action
    """

    def __init__(self,
                 scene_canvas=None,
                 image=None,
                 input_colourspace='ITU-R BT.709',
                 correlate_colourspace='ACEScg',
                 diagram='CIE 1931',
                 **kwargs):
        self._initialised = False

        ViewBox.__init__(self, **kwargs)

        self.unfreeze()

        self._scene_canvas = scene_canvas

        self._image = None
        self.image = image
        self._input_colourspace = None
        self.input_colourspace = input_colourspace
        self._correlate_colourspace = None
        self.correlate_colourspace = correlate_colourspace
        self._diagram = None
        self.diagram = diagram

        self._diagrams_cycle = Cycle(CHROMATICITY_DIAGRAMS)

        self._grid = None

        self._label = None

        self._chromaticity_diagram_visual = None
        self._spectral_locus_visual = None
        self._RGB_scatter_visual = None
        self._input_colourspace_visual = None
        self._correlate_colourspace_visual = None
        self._pointer_gamut_visual = None
        self._pointer_gamut_boundaries_visual = None
        self._grid_visual = None
        self._axis_visual = None

        self._visuals = ('chromaticity_diagram_visual',
                         'spectral_locus_visual', 'RGB_scatter_visual',
                         'input_colourspace_visual',
                         'correlate_colourspace_visual',
                         'pointer_gamut_visual',
                         'pointer_gamut_boundaries_visual', 'grid_visual',
                         'axis_visual')

        self._visuals_visibility = None

        self._create_visuals()
        self._attach_visuals()
        self._create_camera()

        self._create_label()

        self._initialised = True

    @property
    def scene_canvas(self):
        """
        Property for **self.scene_canvas** attribute.

        Returns
        -------
        SceneCanvas
        """

        return self._scene_canvas

    @property
    def image(self):
        """
        Property for **self._image** private attribute.

        Returns
        -------
        array_like
            self._image.
        """

        return self._image

    @image.setter
    def image(self, value):
        """
        Setter for **self._image** private attribute.

        Parameters
        ----------
        value : array_like
            Attribute value.
        """

        if value is not None:
            assert isinstance(value, (tuple, list, np.ndarray, np.matrix)), ((
                '"{0}" attribute: "{1}" is not a "tuple", "list", "ndarray" '
                'or "matrix" instance!').format('image', value))

        self._image = value

        if self._initialised:
            self._store_visuals_visibility()
            self._detach_visuals()
            self._create_RGB_scatter_visual(self._image)
            self._attach_visuals()
            self._restore_visuals_visibility()
            self._label_text()

    @property
    def input_colourspace(self):
        """
        Property for **self._input_colourspace** private attribute.

        Returns
        -------
        unicode
            self._input_colourspace.
        """

        return self._input_colourspace

    @input_colourspace.setter
    def input_colourspace(self, value):
        """
        Setter for **self._input_colourspace** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert is_string(value), (('"{0}" attribute: "{1}" is not a '
                                       '"string" like object!').format(
                                           'input_colourspace', value))
            assert value in RGB_COLOURSPACES, (
                '"{0}" colourspace not found in factory RGB colourspaces: '
                '"{1}".').format(value, ', '.join(
                    sorted(RGB_COLOURSPACES.keys())))

        self._input_colourspace = value

        if self._initialised:
            self._detach_visuals()
            self._create_input_colourspace_visual()
            self._attach_visuals()
            self._label_text()

    @property
    def correlate_colourspace(self):
        """
        Property for **self._correlate_colourspace** private attribute.

        Returns
        -------
        unicode
            self._correlate_colourspace.
        """

        return self._correlate_colourspace

    @correlate_colourspace.setter
    def correlate_colourspace(self, value):
        """
        Setter for **self._correlate_colourspace** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert is_string(value), (('"{0}" attribute: "{1}" is not a '
                                       '"string" like object!').format(
                                           'correlate_colourspace', value))
            assert value in RGB_COLOURSPACES, (
                '"{0}" colourspace not found in factory RGB colourspaces: '
                '"{1}".').format(value, ', '.join(
                    sorted(RGB_COLOURSPACES.keys())))
        self._correlate_colourspace = value

        if self._initialised:
            self._detach_visuals()
            self._create_correlate_colourspace_visual()
            self._attach_visuals()
            self._label_text()

    @property
    def diagram(self):
        """
        Property for **self._diagram** private attribute.

        Returns
        -------
        unicode
            self._diagram.
        """

        return self._diagram

    @diagram.setter
    def diagram(self, value):
        """
        Setter for **self._diagram** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert is_string(value), (('"{0}" attribute: "{1}" is not a '
                                       '"string" like object!').format(
                                           'input_colourspace', value))
            assert value in CHROMATICITY_DIAGRAMS, (
                '"{0}" diagram not found in factory chromaticity diagrams: '
                '"{1}".').format(value, ', '.join(
                    sorted(CHROMATICITY_DIAGRAMS.keys())))

        if self._initialised:
            self._store_visuals_visibility()
            self._detach_visuals()

        self._diagram = value

        if self._initialised:
            self._create_visuals()
            self._attach_visuals()
            self._restore_visuals_visibility()
            self._label_text()

    def _create_chromaticity_diagram_visual(self, diagram=None):
        """
        Creates the given chromaticity diagram visual.

        Parameters
        ----------
        diagram : unicode, optional
            **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
            Chromaticity diagram to draw.
        """

        diagram = self._diagram if diagram is None else diagram

        diagrams = {
            'CIE 1931': CIE_1931_chromaticity_diagram,
            'CIE 1960 UCS': CIE_1960_UCS_chromaticity_diagram,
            'CIE 1976 UCS': CIE_1976_UCS_chromaticity_diagram
        }

        self._chromaticity_diagram_visual = diagrams[diagram]()

    def _create_spectral_locus_visual(self):
        """
        Creates the spectral locus visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self._spectral_locus_visual = spectral_locus_visual(
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self._diagram]),
            uniform_colour=(0.0, 0.0, 0.0),
            width=2.0,
            method='agg')

    def _create_RGB_scatter_visual(self, RGB=None):
        """
        Creates the *RGB* scatter visual for given *RGB* array according to
        :attr:`DiagramView.diagram` attribute value.

        Parameters
        ----------
        RGB : array_like, optional
            *RGB* array to draw.
        """

        RGB = self._image if RGB is None else RGB

        self._RGB_scatter_visual = RGB_scatter_visual(
            RGB,
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self._diagram]),
            uniform_colour=(0.0, 0.0, 0.0))

    def _create_pointer_gamut_visual(self):
        """
        Creates the *Pointer's Gamut* visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self._pointer_gamut_visual = pointer_gamut_visual(
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self._diagram]),
            uniform_opacity=0.4)

    def _create_pointer_gamut_boundaries_visual(self):
        """
        Creates the *Pointer's Gamut* boundaries visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self._pointer_gamut_boundaries_visual = (
            pointer_gamut_boundaries_visual(
                reference_colourspace=(
                    CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[
                        self._diagram])))

    def _create_input_colourspace_visual(self):
        """
        Creates the input colourspace visual according to
        :attr:`DiagramView.input_colourspace` attribute value.
        """

        self._input_colourspace_visual = RGB_colourspace_triangle_visual(
            self._input_colourspace,
            self._diagram,
            uniform_colour=(0.8, 0.0, 0.8))

    def _create_correlate_colourspace_visual(self):
        """
        Creates the correlate colourspace visual according to
        :attr:`DiagramView.correlate_colourspace` attribute value.
        """

        self._correlate_colourspace_visual = RGB_colourspace_triangle_visual(
            self._correlate_colourspace,
            self._diagram,
            uniform_colour=(0.0, 0.8, 0.8))

    def _create_grid_visual(self):
        """
        Creates the grid visual.
        """

        self._grid_visual = GridLines()

    def _create_axis_visual(self):
        """
        Creates the axis visual.
        """

        self._axis_visual = axis_visual()

    def _create_visuals(self):
        """
        Creates the *Diagram View* visuals.
        """

        for visual in self._visuals:
            visual = '_create_{0}'.format(visual)
            getattr(self, visual)()

    def _create_camera(self):
        """
        Creates the *Diagram View* camera.
        """

        self.camera = PanZoomCamera(rect=(-0.1, -0.1, 1.1, 1.1), aspect=1)

    def _attach_visuals(self):
        """
        Attaches / parents the visuals to the *Diagram View* scene.
        """

        for visual in self._visuals:
            visual = '_{0}'.format(visual)
            getattr(self, visual).parent = self.scene

    def _detach_visuals(self):
        """
        Detaches / un-parents the visuals from the *Diagram View* scene.
        """

        for visual in self._visuals:
            visual = '_{0}'.format(visual)
            getattr(self, visual).parent = None

    def _store_visuals_visibility(self):
        """
        Stores visuals visibility in :attr:`DiagramView._visuals_visibility`
        attribute.
        """

        visibility = OrderedDict()
        for visual in self._visuals:
            visibility[visual] = getattr(self, '_{0}'.format(visual)).visible

        self._visuals_visibility = visibility

    def _restore_visuals_visibility(self):
        """
        Restores visuals visibility from
        :attr:`DiagramView._visuals_visibility` attribute.
        """

        visibility = self._visuals_visibility
        for visual in self._visuals:
            getattr(self, '_{0}'.format(visual)).visible = (visibility[visual])

    def _create_label(self):
        """
        Creates the label.
        """

        self._label = Label(str(), color=(0.8, 0.8, 0.8))
        self._label.stretch = (1, 0.1)
        self._grid = self.add_grid(margin=16)
        self._grid.add_widget(self._label, row=0, col=0)
        self._grid.add_widget(Widget(), row=1, col=0)

        self._label_text()

    def _label_text(self):
        """
        Sets the label text.
        """

        title = ''

        if self._input_colourspace_visual.visible:
            title += self._input_colourspace
            title += ' - '
        if self._correlate_colourspace_visual.visible:
            title += self._correlate_colourspace
            title += ' - '

        title += '{0} Chromaticity Diagram'.format(self._diagram)

        if self.scene_canvas.clamp_blacks:
            title += ' - '
            title += 'Blacks Clamped'

        if self.scene_canvas.clamp_whites:
            title += ' - '
            title += 'Whites Clamped'

        self._label.text = title

    def toggle_spectral_locus_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_spectral_locus_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._spectral_locus_visual.visible = (
            not self._spectral_locus_visual.visible)

        return True

    def toggle_input_colourspace_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_input_colourspace_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._input_colourspace_visual.visible = (
            not self._input_colourspace_visual.visible)
        self._label_text()

        return True

    def toggle_correlate_colourspace_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_correlate_colourspace_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._correlate_colourspace_visual.visible = (
            not self._correlate_colourspace_visual.visible)
        self._label_text()

        return True

    def toggle_RGB_scatter_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_RGB_scatter_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._RGB_scatter_visual.visible = (
            not self._RGB_scatter_visual.visible)

        return True

    def toggle_pointer_gamut_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_pointer_gamut_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._pointer_gamut_visual.visible = (
            not self._pointer_gamut_visual.visible)
        self._pointer_gamut_boundaries_visual.visible = (
            not self._pointer_gamut_boundaries_visual.visible)

        return True

    def toggle_grid_visual_visibility_action(self):
        """
        Defines the slot triggered by the *toggle_grid_visual_visibility*
        action.

        Returns
        -------
        bool
            Definition success.
        """

        self._grid_visual.visible = not self._grid_visual.visible

        return True

    def toggle_axis_visual_visibility_action(self):
        """
        Defines the slot triggered by the *toggle_axis_visual_visibility*
        action.

        Returns
        -------
        bool
            Definition success.
        """

        self._axis_visual.visible = (not self._axis_visual.visible)

        return True

    def cycle_chromaticity_diagram_action(self):
        """
        Defines the slot triggered by the *cycle_chromaticity_diagram* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.diagram = self._diagrams_cycle.next_item()

        return True
Exemplo n.º 6
0
class DiagramView(ViewBox):
    """
    Defines the *Diagram View*.

    Parameters
    ----------
    canvas : SceneCanvas, optional
        Current `vispy.scene.SceneCanvas` instance.
    image : array_like, optional
        Image to use in the view interactions.
    input_colourspace : unicode, optional
        See `oecf` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the
        `image` argument colourspace.
    correlate_colourspace : unicode, optional
        See `oecf` argument for possible values, default value is *ACEScg*.

        :class:`colour.RGB_Colourspace` class instance name defining the
        comparison / correlate colourspace.
    diagram : unicode, optional
        {'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}

        Chromaticity diagram to draw.
    \*\*kwargs : \*\*, optional
        Keywords arguments passed to
        :class:`vispy.scene.widgets.viewbox.Viewbox` class constructor.

    Attributes
    ----------
    canvas
    image
    input_colourspace
    correlate_colourspace
    diagram

    Methods
    -------
    toggle_spectral_locus_visual_visibility_action
    toggle_input_colourspace_visual_visibility_action
    toggle_correlate_colourspace_visual_visibility_action
    toggle_RGB_scatter_visual_visibility_action
    toggle_pointer_gamut_visual_visibility_action
    toggle_grid_visual_visibility_action
    toggle_axis_visual_visibility_action
    cycle_chromaticity_diagram_action
    """

    def __init__(self,
                 canvas=None,
                 image=None,
                 input_colourspace='Rec. 709',
                 correlate_colourspace='ACEScg',
                 diagram='CIE 1931',
                 **kwargs):
        self.__initialised = False

        ViewBox.__init__(self, **kwargs)

        self.__canvas = canvas

        self.__image = None
        self.image = image
        self.__input_colourspace = None
        self.input_colourspace = input_colourspace
        self.__correlate_colourspace = None
        self.correlate_colourspace = correlate_colourspace
        self.__diagram = None
        self.diagram = diagram

        self.__diagrams_cycle = Cycle(CHROMATICITY_DIAGRAMS)

        self.__title_overlay_visual = None

        self.__chromaticity_diagram_visual = None
        self.__spectral_locus_visual = None
        self.__RGB_scatter_visual = None
        self.__input_colourspace_visual = None
        self.__correlate_colourspace_visual = None
        self.__pointer_gamut_visual = None
        self.__pointer_gamut_boundaries_visual = None
        self.__grid_visual = None
        self.__axis_visual = None

        self.__visuals = ('chromaticity_diagram_visual',
                          'spectral_locus_visual',
                          'RGB_scatter_visual',
                          'input_colourspace_visual',
                          'correlate_colourspace_visual',
                          'pointer_gamut_visual',
                          'pointer_gamut_boundaries_visual',
                          'grid_visual',
                          'axis_visual')

        self.__visuals_visibility = None

        self.__create_visuals()
        self.__attach_visuals()
        self.__create_camera()

        self.__create_title_overlay_visual()
        self.__canvas.events.resize.connect(self.__canvas_resize_event)

        self.__initialised = True

    @property
    def canvas(self):
        """
        Property for **self.canvas** attribute.

        Returns
        -------
        SceneCanvas
        """

        return self.__canvas

    @canvas.setter
    def canvas(self, value):
        """
        Setter for **self.canvas** attribute.

        Parameters
        ----------
        value : SceneCanvas
            Attribute value.
        """

        raise AttributeError('"{0}" attribute is read only!'.format('canvas'))

    @property
    def image(self):
        """
        Property for **self.__image** private attribute.

        Returns
        -------
        array_like
            self.__image.
        """

        return self.__image

    @image.setter
    def image(self, value):
        """
        Setter for **self.__image** private attribute.

        Parameters
        ----------
        value : array_like
            Attribute value.
        """

        if value is not None:
            assert type(value) in (tuple, list, np.ndarray, np.matrix), (
                ('"{0}" attribute: "{1}" type is not "tuple", "list", '
                 '"ndarray" or "matrix"!').format('image', value))

        self.__image = value

        if self.__initialised:
            self.__store_visuals_visibility()
            self.__detach_visuals()
            self.__create_RGB_scatter_visual(self.__image)
            self.__attach_visuals()
            self.__restore_visuals_visibility()
            self.__title_overlay_visual_text()

    @property
    def input_colourspace(self):
        """
        Property for **self.__input_colourspace** private attribute.

        Returns
        -------
        unicode
            self.__input_colourspace.
        """

        return self.__input_colourspace

    @input_colourspace.setter
    def input_colourspace(self, value):
        """
        Setter for **self.__input_colourspace** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert type(value) in (str, unicode), (
                ('"{0}" attribute: "{1}" type is not '
                 '"str" or "unicode"!').format('input_colourspace', value))
            assert value in RGB_COLOURSPACES, (
                '"{0}" colourspace not found in factory RGB colourspaces: '
                '"{1}".').format(
                value, ', '.join(sorted(RGB_COLOURSPACES.keys())))

        self.__input_colourspace = value

        if self.__initialised:
            self.__detach_visuals()
            self.__create_input_colourspace_visual()
            self.__attach_visuals()
            self.__title_overlay_visual_text()

    @property
    def correlate_colourspace(self):
        """
        Property for **self.__correlate_colourspace** private attribute.

        Returns
        -------
        unicode
            self.__correlate_colourspace.
        """

        return self.__correlate_colourspace

    @correlate_colourspace.setter
    def correlate_colourspace(self, value):
        """
        Setter for **self.__correlate_colourspace** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert type(value) in (str, unicode), (
                ('"{0}" attribute: "{1}" type is not '
                 '"str" or "unicode"!').format('correlate_colourspace', value))
            assert value in RGB_COLOURSPACES, (
                '"{0}" colourspace not found in factory RGB colourspaces: '
                '"{1}".').format(value, ', '.join(
                sorted(RGB_COLOURSPACES.keys())))
        self.__correlate_colourspace = value

        if self.__initialised:
            self.__detach_visuals()
            self.__create_correlate_colourspace_visual()
            self.__attach_visuals()
            self.__title_overlay_visual_text()

    @property
    def diagram(self):
        """
        Property for **self.__diagram** private attribute.

        Returns
        -------
        unicode
            self.__diagram.
        """

        return self.__diagram

    @diagram.setter
    def diagram(self, value):
        """
        Setter for **self.__diagram** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert type(value) in (str, unicode), (
                ('"{0}" attribute: "{1}" type is not '
                 '"str" or "unicode"!').format('diagram', value))
            assert value in CHROMATICITY_DIAGRAMS, (
                '"{0}" diagram not found in factory chromaticity diagrams: '
                '"{1}".').format(value, ', '.join(
                sorted(CHROMATICITY_DIAGRAMS.keys())))

        if self.__initialised:
            self.__store_visuals_visibility()
            self.__detach_visuals()

        self.__diagram = value

        if self.__initialised:
            self.__create_visuals()
            self.__attach_visuals()
            self.__restore_visuals_visibility()
            self.__title_overlay_visual_text()

    def __create_chromaticity_diagram_visual(self, diagram=None):
        """
        Creates the given chromaticity diagram visual.

        Parameters
        ----------
        diagram : unicode, optional
            {'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}

            Chromaticity diagram to draw.
        """

        diagram = self.__diagram if diagram is None else diagram

        diagrams = {'CIE 1931': CIE_1931_chromaticity_diagram,
                    'CIE 1960 UCS': CIE_1960_UCS_chromaticity_diagram,
                    'CIE 1976 UCS': CIE_1976_UCS_chromaticity_diagram}

        self.__chromaticity_diagram_visual = diagrams[diagram]()

    def __create_spectral_locus_visual(self):
        """
        Creates the spectral locus visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self.__spectral_locus_visual = spectral_locus_visual(
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self.__diagram]),
            uniform_colour=(0.0, 0.0, 0.0),
            width=2.0,
            method='agg')

    def __create_RGB_scatter_visual(self, RGB=None):
        """
        Creates the *RGB* scatter visual for given *RGB* array according to
        :attr:`DiagramView.diagram` attribute value.

        Parameters
        ----------
        RGB : array_like, optional
            *RGB* array to draw.
        """

        RGB = self.__image if RGB is None else RGB

        self.__RGB_scatter_visual = RGB_scatter_visual(
            RGB,
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self.__diagram]),
            uniform_colour=(0.0, 0.0, 0.0))

    def __create_pointer_gamut_visual(self):
        """
        Creates the *Pointer's Gamut* visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self.__pointer_gamut_visual = pointer_gamut_visual(
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self.__diagram]),
            uniform_opacity=0.4)

    def __create_pointer_gamut_boundaries_visual(self):
        """
        Creates the *Pointer's Gamut* boundaries visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self.__pointer_gamut_boundaries_visual = (
            pointer_gamut_boundaries_visual(reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[
                    self.__diagram])))

    def __create_input_colourspace_visual(self):
        """
        Creates the input colourspace visual according to
        :attr:`DiagramView.input_colourspace` attribute value.
        """

        self.__input_colourspace_visual = RGB_colourspace_triangle_visual(
            self.__input_colourspace,
            self.__diagram,
            uniform_colour=(0.8, 0.0, 0.8))

    def __create_correlate_colourspace_visual(self):
        """
        Creates the correlate colourspace visual according to
        :attr:`DiagramView.correlate_colourspace` attribute value.
        """

        self.__correlate_colourspace_visual = RGB_colourspace_triangle_visual(
            self.__correlate_colourspace,
            self.__diagram,
            uniform_colour=(0.0, 0.8, 0.8))

    def __create_grid_visual(self):
        """
        Creates the grid visual.
        """

        self.__grid_visual = GridLines()

    def __create_axis_visual(self):
        """
        Creates the axis visual.
        """

        self.__axis_visual = axis_visual()

    def __create_visuals(self):
        """
        Creates the *Diagram View* visuals.
        """

        for visual in self.__visuals:
            visual = '_DiagramView__create_{0}'.format(visual)
            getattr(self, visual)()

    def __create_camera(self):
        """
        Creates the *Diagram View* camera.
        """

        self.camera = PanZoomCamera(rect=(-0.1, -0.1, 1.1, 1.1),
                                    aspect=1)

    def __attach_visuals(self):
        """
        Attaches / parents the visuals to the *Diagram View* scene.
        """

        for visual in self.__visuals:
            visual = '_DiagramView__{0}'.format(visual)
            getattr(self, visual).add_parent(self.scene)

    def __detach_visuals(self):
        """
        Detaches / un-parents the visuals from the *Diagram View* scene.
        """

        for visual in self.__visuals:
            visual = '_DiagramView__{0}'.format(visual)
            getattr(self, visual).remove_parent(self.scene)

    def __store_visuals_visibility(self):
        """
        Stores visuals visibility in :attr:`DiagramView.__visuals_visibility`
        attribute.
        """

        visibility = OrderedDict()
        for visual in self.__visuals:
            visibility[visual] = (
                getattr(self, '_DiagramView__{0}'.format(visual)).visible)

        self.__visuals_visibility = visibility

    def __restore_visuals_visibility(self):
        """
        Restores visuals visibility from
        :attr:`DiagramView.__visuals_visibility` attribute.
        """

        visibility = self.__visuals_visibility
        for visual in self.__visuals:
            getattr(self, '_DiagramView__{0}'.format(visual)).visible = (
                visibility[visual])

    def __create_title_overlay_visual(self):
        """
        Creates the title overlay visual.
        """

        self.__title_overlay_visual = Text(str(),
                                           anchor_x='center',
                                           anchor_y='bottom',
                                           font_size=10,
                                           color=(0.8, 0.8, 0.8),
                                           parent=self)

        self.__title_overlay_visual_position()
        self.__title_overlay_visual_text()

    def __title_overlay_visual_position(self):
        """
        Sets the title overlay visual position.
        """

        self.__title_overlay_visual.pos = self.size[0] / 2, 32

    def __title_overlay_visual_text(self):
        """
        Sets the title overlay visual text.
        """

        title = ''

        if self.__input_colourspace_visual.visible:
            title += self.__input_colourspace
            title += ' - '
        if self.__correlate_colourspace_visual.visible:
            title += self.__correlate_colourspace
            title += ' - '

        title += '{0} Chromaticity Diagram'.format(self.__diagram)

        if self.__canvas.clamp_blacks:
            title += ' - '
            title += 'Blacks Clamped'

        if self.__canvas.clamp_whites:
            title += ' - '
            title += 'Whites Clamped'

        self.__title_overlay_visual.text = title

    def __canvas_resize_event(self, event=None):
        """
        Slot for current :class:`vispy.scene.SceneCanvas` instance resize
        event.

        Parameters
        ----------
        event : Object
            Event.
        """

        self.__title_overlay_visual_position()

    def toggle_spectral_locus_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_spectral_locus_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.__spectral_locus_visual.visible = (
            not self.__spectral_locus_visual.visible)

        return True

    def toggle_input_colourspace_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_input_colourspace_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.__input_colourspace_visual.visible = (
            not self.__input_colourspace_visual.visible)
        self.__title_overlay_visual_text()

        return True

    def toggle_correlate_colourspace_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_correlate_colourspace_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.__correlate_colourspace_visual.visible = (
            not self.__correlate_colourspace_visual.visible)
        self.__title_overlay_visual_text()

        return True

    def toggle_RGB_scatter_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_RGB_scatter_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.__RGB_scatter_visual.visible = (
            not self.__RGB_scatter_visual.visible)

        return True

    def toggle_pointer_gamut_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_pointer_gamut_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.__pointer_gamut_visual.visible = (
            not self.__pointer_gamut_visual.visible)
        self.__pointer_gamut_boundaries_visual.visible = (
            not self.__pointer_gamut_boundaries_visual.visible)

        return True

    def toggle_grid_visual_visibility_action(self):
        """
        Defines the slot triggered by the *toggle_grid_visual_visibility*
        action.

        Returns
        -------
        bool
            Definition success.
        """

        self.__grid_visual.visible = not self.__grid_visual.visible

        return True

    def toggle_axis_visual_visibility_action(self):
        """
        Defines the slot triggered by the *toggle_axis_visual_visibility*
        action.

        Returns
        -------
        bool
            Definition success.
        """

        self.__axis_visual.visible = (
            not self.__axis_visual.visible)

        return True

    def cycle_chromaticity_diagram_action(self):
        """
        Defines the slot triggered by the *cycle_chromaticity_diagram* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.diagram = self.__diagrams_cycle.next_item()

        return True
class DiagramView(ViewBox):
    """
    Defines the *Diagram View*.

    Parameters
    ----------
    scene_canvas : SceneCanvas, optional
        Current `vispy.scene.SceneCanvas` instance.
    image : array_like, optional
        Image to use in the view interactions.
    input_colourspace : unicode, optional
        See `oecf` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the
        `image` argument colourspace.
    correlate_colourspace : unicode, optional
        See `oecf` argument for possible values, default value is *ACEScg*.

        :class:`colour.RGB_Colourspace` class instance name defining the
        comparison / correlate colourspace.
    diagram : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Chromaticity diagram to draw.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        Keywords arguments passed to
        :class:`vispy.scene.widgets.viewbox.Viewbox` class constructor.

    Attributes
    ----------
    scene_canvas
    image
    input_colourspace
    correlate_colourspace
    diagram

    Methods
    -------
    toggle_spectral_locus_visual_visibility_action
    toggle_input_colourspace_visual_visibility_action
    toggle_correlate_colourspace_visual_visibility_action
    toggle_RGB_scatter_visual_visibility_action
    toggle_pointer_gamut_visual_visibility_action
    toggle_grid_visual_visibility_action
    toggle_axis_visual_visibility_action
    cycle_chromaticity_diagram_action
    """

    def __init__(self,
                 scene_canvas=None,
                 image=None,
                 input_colourspace='ITU-R BT.709',
                 correlate_colourspace='ACEScg',
                 diagram='CIE 1931',
                 **kwargs):
        self._initialised = False

        ViewBox.__init__(self, **kwargs)

        self.unfreeze()

        self._scene_canvas = scene_canvas

        self._image = None
        self.image = image
        self._input_colourspace = None
        self.input_colourspace = input_colourspace
        self._correlate_colourspace = None
        self.correlate_colourspace = correlate_colourspace
        self._diagram = None
        self.diagram = diagram

        self._diagrams_cycle = Cycle(CHROMATICITY_DIAGRAMS)

        self._grid = None

        self._label = None

        self._chromaticity_diagram_visual = None
        self._spectral_locus_visual = None
        self._RGB_scatter_visual = None
        self._input_colourspace_visual = None
        self._correlate_colourspace_visual = None
        self._pointer_gamut_visual = None
        self._pointer_gamut_boundaries_visual = None
        self._grid_visual = None
        self._axis_visual = None

        self._visuals = ('chromaticity_diagram_visual',
                         'spectral_locus_visual', 'RGB_scatter_visual',
                         'input_colourspace_visual',
                         'correlate_colourspace_visual',
                         'pointer_gamut_visual',
                         'pointer_gamut_boundaries_visual', 'grid_visual',
                         'axis_visual')

        self._visuals_visibility = None

        self._create_visuals()
        self._attach_visuals()
        self._create_camera()

        self._create_label()

        self._initialised = True

    @property
    def scene_canvas(self):
        """
        Property for **self.scene_canvas** attribute.

        Returns
        -------
        SceneCanvas
        """

        return self._scene_canvas

    @property
    def image(self):
        """
        Property for **self._image** private attribute.

        Returns
        -------
        array_like
            self._image.
        """

        return self._image

    @image.setter
    def image(self, value):
        """
        Setter for **self._image** private attribute.

        Parameters
        ----------
        value : array_like
            Attribute value.
        """

        if value is not None:
            assert isinstance(value, (tuple, list, np.ndarray, np.matrix)), ((
                '"{0}" attribute: "{1}" is not a "tuple", "list", "ndarray" '
                'or "matrix" instance!').format('image', value))

        self._image = value

        if self._initialised:
            self._store_visuals_visibility()
            self._detach_visuals()
            self._create_RGB_scatter_visual(self._image)
            self._attach_visuals()
            self._restore_visuals_visibility()
            self._label_text()

    @property
    def input_colourspace(self):
        """
        Property for **self._input_colourspace** private attribute.

        Returns
        -------
        unicode
            self._input_colourspace.
        """

        return self._input_colourspace

    @input_colourspace.setter
    def input_colourspace(self, value):
        """
        Setter for **self._input_colourspace** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert is_string(value), (('"{0}" attribute: "{1}" is not a '
                                       '"string" like object!').format(
                                           'input_colourspace', value))
            assert value in RGB_COLOURSPACES, (
                '"{0}" colourspace not found in factory RGB colourspaces: '
                '"{1}".').format(value, ', '.join(
                    sorted(RGB_COLOURSPACES.keys())))

        self._input_colourspace = value

        if self._initialised:
            self._detach_visuals()
            self._create_input_colourspace_visual()
            self._attach_visuals()
            self._label_text()

    @property
    def correlate_colourspace(self):
        """
        Property for **self._correlate_colourspace** private attribute.

        Returns
        -------
        unicode
            self._correlate_colourspace.
        """

        return self._correlate_colourspace

    @correlate_colourspace.setter
    def correlate_colourspace(self, value):
        """
        Setter for **self._correlate_colourspace** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert is_string(value), (('"{0}" attribute: "{1}" is not a '
                                       '"string" like object!').format(
                                           'correlate_colourspace', value))
            assert value in RGB_COLOURSPACES, (
                '"{0}" colourspace not found in factory RGB colourspaces: '
                '"{1}".').format(value, ', '.join(
                    sorted(RGB_COLOURSPACES.keys())))
        self._correlate_colourspace = value

        if self._initialised:
            self._detach_visuals()
            self._create_correlate_colourspace_visual()
            self._attach_visuals()
            self._label_text()

    @property
    def diagram(self):
        """
        Property for **self._diagram** private attribute.

        Returns
        -------
        unicode
            self._diagram.
        """

        return self._diagram

    @diagram.setter
    def diagram(self, value):
        """
        Setter for **self._diagram** private attribute.

        Parameters
        ----------
        value : unicode
            Attribute value.
        """

        if value is not None:
            assert is_string(value), (('"{0}" attribute: "{1}" is not a '
                                       '"string" like object!').format(
                                           'input_colourspace', value))
            assert value in CHROMATICITY_DIAGRAMS, (
                '"{0}" diagram not found in factory chromaticity diagrams: '
                '"{1}".').format(value, ', '.join(
                    sorted(CHROMATICITY_DIAGRAMS.keys())))

        if self._initialised:
            self._store_visuals_visibility()
            self._detach_visuals()

        self._diagram = value

        if self._initialised:
            self._create_visuals()
            self._attach_visuals()
            self._restore_visuals_visibility()
            self._label_text()

    def _create_chromaticity_diagram_visual(self, diagram=None):
        """
        Creates the given chromaticity diagram visual.

        Parameters
        ----------
        diagram : unicode, optional
            **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
            Chromaticity diagram to draw.
        """

        diagram = self._diagram if diagram is None else diagram

        diagrams = {
            'CIE 1931': CIE_1931_chromaticity_diagram,
            'CIE 1960 UCS': CIE_1960_UCS_chromaticity_diagram,
            'CIE 1976 UCS': CIE_1976_UCS_chromaticity_diagram
        }

        self._chromaticity_diagram_visual = diagrams[diagram]()

    def _create_spectral_locus_visual(self):
        """
        Creates the spectral locus visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self._spectral_locus_visual = spectral_locus_visual(
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self._diagram]),
            uniform_colour=(0.0, 0.0, 0.0),
            width=2.0,
            method='agg')

    def _create_RGB_scatter_visual(self, RGB=None):
        """
        Creates the *RGB* scatter visual for given *RGB* array according to
        :attr:`DiagramView.diagram` attribute value.

        Parameters
        ----------
        RGB : array_like, optional
            *RGB* array to draw.
        """

        RGB = self._image if RGB is None else RGB

        self._RGB_scatter_visual = RGB_scatter_visual(
            RGB,
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self._diagram]),
            uniform_colour=(0.0, 0.0, 0.0))

    def _create_pointer_gamut_visual(self):
        """
        Creates the *Pointer's Gamut* visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self._pointer_gamut_visual = pointer_gamut_visual(
            reference_colourspace=(
                CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[self._diagram]),
            uniform_opacity=0.4)

    def _create_pointer_gamut_boundaries_visual(self):
        """
        Creates the *Pointer's Gamut* boundaries visual according to
        :attr:`DiagramView.diagram` attribute value.
        """

        self._pointer_gamut_boundaries_visual = (
            pointer_gamut_boundaries_visual(
                reference_colourspace=(
                    CHROMATICITY_DIAGRAM_TO_REFERENCE_COLOURSPACE[
                        self._diagram])))

    def _create_input_colourspace_visual(self):
        """
        Creates the input colourspace visual according to
        :attr:`DiagramView.input_colourspace` attribute value.
        """

        self._input_colourspace_visual = RGB_colourspace_triangle_visual(
            self._input_colourspace,
            self._diagram,
            uniform_colour=(0.8, 0.0, 0.8))

    def _create_correlate_colourspace_visual(self):
        """
        Creates the correlate colourspace visual according to
        :attr:`DiagramView.correlate_colourspace` attribute value.
        """

        self._correlate_colourspace_visual = RGB_colourspace_triangle_visual(
            self._correlate_colourspace,
            self._diagram,
            uniform_colour=(0.0, 0.8, 0.8))

    def _create_grid_visual(self):
        """
        Creates the grid visual.
        """

        self._grid_visual = GridLines()

    def _create_axis_visual(self):
        """
        Creates the axis visual.
        """

        self._axis_visual = axis_visual()

    def _create_visuals(self):
        """
        Creates the *Diagram View* visuals.
        """

        for visual in self._visuals:
            visual = '_create_{0}'.format(visual)
            getattr(self, visual)()

    def _create_camera(self):
        """
        Creates the *Diagram View* camera.
        """

        self.camera = PanZoomCamera(rect=(-0.1, -0.1, 1.1, 1.1), aspect=1)

    def _attach_visuals(self):
        """
        Attaches / parents the visuals to the *Diagram View* scene.
        """

        for visual in self._visuals:
            visual = '_{0}'.format(visual)
            getattr(self, visual).parent = self.scene

    def _detach_visuals(self):
        """
        Detaches / un-parents the visuals from the *Diagram View* scene.
        """

        for visual in self._visuals:
            visual = '_{0}'.format(visual)
            getattr(self, visual).parent = None

    def _store_visuals_visibility(self):
        """
        Stores visuals visibility in :attr:`DiagramView._visuals_visibility`
        attribute.
        """

        visibility = OrderedDict()
        for visual in self._visuals:
            visibility[visual] = getattr(self, '_{0}'.format(visual)).visible

        self._visuals_visibility = visibility

    def _restore_visuals_visibility(self):
        """
        Restores visuals visibility from
        :attr:`DiagramView._visuals_visibility` attribute.
        """

        visibility = self._visuals_visibility
        for visual in self._visuals:
            getattr(self, '_{0}'.format(visual)).visible = (visibility[visual])

    def _create_label(self):
        """
        Creates the label.
        """

        self._label = Label(str(), color=(0.8, 0.8, 0.8))
        self._label.stretch = (1, 0.1)
        self._grid = self.add_grid(margin=16)
        self._grid.add_widget(self._label, row=0, col=0)
        self._grid.add_widget(Widget(), row=1, col=0)

        self._label_text()

    def _label_text(self):
        """
        Sets the label text.
        """

        title = ''

        if self._input_colourspace_visual.visible:
            title += self._input_colourspace
            title += ' - '
        if self._correlate_colourspace_visual.visible:
            title += self._correlate_colourspace
            title += ' - '

        title += '{0} Chromaticity Diagram'.format(self._diagram)

        if self.scene_canvas.clamp_blacks:
            title += ' - '
            title += 'Blacks Clamped'

        if self.scene_canvas.clamp_whites:
            title += ' - '
            title += 'Whites Clamped'

        self._label.text = title

    def toggle_spectral_locus_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_spectral_locus_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._spectral_locus_visual.visible = (
            not self._spectral_locus_visual.visible)

        return True

    def toggle_input_colourspace_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_input_colourspace_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._input_colourspace_visual.visible = (
            not self._input_colourspace_visual.visible)
        self._label_text()

        return True

    def toggle_correlate_colourspace_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_correlate_colourspace_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._correlate_colourspace_visual.visible = (
            not self._correlate_colourspace_visual.visible)
        self._label_text()

        return True

    def toggle_RGB_scatter_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_RGB_scatter_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._RGB_scatter_visual.visible = (
            not self._RGB_scatter_visual.visible)

        return True

    def toggle_pointer_gamut_visual_visibility_action(self):
        """
        Defines the slot triggered by the
        *toggle_pointer_gamut_visual_visibility* action.

        Returns
        -------
        bool
            Definition success.
        """

        self._pointer_gamut_visual.visible = (
            not self._pointer_gamut_visual.visible)
        self._pointer_gamut_boundaries_visual.visible = (
            not self._pointer_gamut_boundaries_visual.visible)

        return True

    def toggle_grid_visual_visibility_action(self):
        """
        Defines the slot triggered by the *toggle_grid_visual_visibility*
        action.

        Returns
        -------
        bool
            Definition success.
        """

        self._grid_visual.visible = not self._grid_visual.visible

        return True

    def toggle_axis_visual_visibility_action(self):
        """
        Defines the slot triggered by the *toggle_axis_visual_visibility*
        action.

        Returns
        -------
        bool
            Definition success.
        """

        self._axis_visual.visible = (not self._axis_visual.visible)

        return True

    def cycle_chromaticity_diagram_action(self):
        """
        Defines the slot triggered by the *cycle_chromaticity_diagram* action.

        Returns
        -------
        bool
            Definition success.
        """

        self.diagram = self._diagrams_cycle.next_item()

        return True