Source code for fsleyes_widgets.colourbutton

#!/usr/bin/env python
#
# colourbutton.py - A button which allows the user to select a colour.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module provides the :class:`ColourButton` class, a button which
allows the user to select a RGBA colour.
"""


import wx
import wx.lib.newevent as wxevent

import fsleyes_widgets as fw


[docs] class ColourButton(wx.Button): """A :class:`wx.Button` which allows the user to select a colour. The currently selected colour is displayed as a bitmap on the button. When the user presses the button, a :class:`wx.ColourDialog` is displayed, allowing the user to change the colour. When the user does so, a :data:`EVT_COLOUR_BUTTON_EVENT` is generated. This class provides an alternative to the :class:`wx.ColourPickerCtrl`, which is a bit inflexible w.r.t. sizing/automatic resizing. """ def __init__(self, parent, size=None, colour=None): """Create a ``ColourButton``. :arg parent: A :mod:`wx` parent window. :arg size: A tuple containing the ``(width, height)`` of the colour bitmap in pixels. Defaults to ``(32, 32)``. :arg colour: Initial colour. Defaults to black. """ if size is None: size = (32, 32) if colour is None: colour = (0, 0, 0, 255) style = wx.BU_EXACTFIT | wx.BU_NOTEXT wx.Button.__init__(self, parent, style=style) # Under wxPython-phoenix, setting # label='' results in "Button". if fw.wxFlavour() == fw.WX_PHOENIX: self.SetLabel(' ') self.__size = size self.__bmp = None self.Bind(wx.EVT_BUTTON, self.__onClick) self.SetValue(colour) self.SetMinSize(self.GetBestSize())
[docs] def GetValue(self): """Return the current colour, as a tuple of ``(r, g, b, a)`` values, each in the range ``[0 - 255]``. """ return self.__colour
[docs] def SetValue(self, colour): """Sets the current colour to the specified ``colour``.""" if len(colour) not in (3, 4): raise ValueError('Invalid RGB[A] colour: {}'.format(colour)) if len(colour) == 3: colour = list(colour) + [255] if any([v < 0 or v > 255 for v in colour]): raise ValueError('Invalid RGBA colour: {}'.format(colour)) self.__updateBitmap(colour) self.__colour = colour
def __updateBitmap(self, colour): """Called when the colour is changed. Updates the bitmap shown on the button. """ import numpy as np w, h = self.__size data = np.zeros((w, h, 4), dtype=np.uint8) data[:, :] = colour if fw.wxFlavour() == fw.WX_PHOENIX: self.__bmp = wx.Bitmap.FromBufferRGBA(w, h, data) else: self.__bmp = wx.BitmapFromBufferRGBA( w, h, data) self.SetBitmap(self.__bmp) def __onClick(self, ev): """Called when this ``ColourButton`` is pressed. Displays a :class:`wx.ColourDialog` allowing the user to select a new colour. """ colourData = wx.ColourData() colourData.SetColour(self.__colour) dlg = wx.ColourDialog(self.GetTopLevelParent(), colourData) if dlg.ShowModal() != wx.ID_OK: return newColour = dlg.GetColourData().GetColour() newColour = [newColour.Red(), newColour.Green(), newColour.Blue(), newColour.Alpha()] self.SetValue(newColour) wx.PostEvent(self, ColourButtonEvent(colour=newColour))
_ColourButtonEvent, _EVT_COLOUR_BUTTON_EVENT = wxevent.NewEvent() EVT_COLOUR_BUTTON_EVENT = _EVT_COLOUR_BUTTON_EVENT """Identifier for the :data:`ColourButtonEvent`. """ ColourButtonEvent = _ColourButtonEvent """Event emitted by a ``ColourButton`` when the user changes the selected colour. """