Home | History | Annotate | Download | only in pynche
      1 """Chip viewer and widget.
      2 
      3 In the lower left corner of the main Pynche window, you will see two
      4 ChipWidgets, one for the selected color and one for the nearest color.  The
      5 selected color is the actual RGB value expressed as an X11 #COLOR name. The
      6 nearest color is the named color from the X11 database that is closest to the
      7 selected color in 3D space.  There may be other colors equally close, but the
      8 nearest one is the first one found.
      9 
     10 Clicking on the nearest color chip selects that named color.
     11 
     12 The ChipViewer class includes the entire lower left quandrant; i.e. both the
     13 selected and nearest ChipWidgets.
     14 """
     15 
     16 from tkinter import *
     17 import ColorDB
     18 
     19 
     21 class ChipWidget:
     22     _WIDTH = 150
     23     _HEIGHT = 80
     24 
     25     def __init__(self,
     26                  master = None,
     27                  width  = _WIDTH,
     28                  height = _HEIGHT,
     29                  text   = 'Color',
     30                  initialcolor = 'blue',
     31                  presscmd   = None,
     32                  releasecmd = None):
     33         # create the text label
     34         self.__label = Label(master, text=text)
     35         self.__label.grid(row=0, column=0)
     36         # create the color chip, implemented as a frame
     37         self.__chip = Frame(master, relief=RAISED, borderwidth=2,
     38                             width=width,
     39                             height=height,
     40                             background=initialcolor)
     41         self.__chip.grid(row=1, column=0)
     42         # create the color name
     43         self.__namevar = StringVar()
     44         self.__namevar.set(initialcolor)
     45         self.__name = Entry(master, textvariable=self.__namevar,
     46                             relief=FLAT, justify=CENTER, state=DISABLED,
     47                             font=self.__label['font'])
     48         self.__name.grid(row=2, column=0)
     49         # create the message area
     50         self.__msgvar = StringVar()
     51         self.__name = Entry(master, textvariable=self.__msgvar,
     52                             relief=FLAT, justify=CENTER, state=DISABLED,
     53                             font=self.__label['font'])
     54         self.__name.grid(row=3, column=0)
     55         # set bindings
     56         if presscmd:
     57             self.__chip.bind('<ButtonPress-1>', presscmd)
     58         if releasecmd:
     59             self.__chip.bind('<ButtonRelease-1>', releasecmd)
     60 
     61     def set_color(self, color):
     62         self.__chip.config(background=color)
     63 
     64     def get_color(self):
     65         return self.__chip['background']
     66 
     67     def set_name(self, colorname):
     68         self.__namevar.set(colorname)
     69 
     70     def set_message(self, message):
     71         self.__msgvar.set(message)
     72 
     73     def press(self):
     74         self.__chip.configure(relief=SUNKEN)
     75 
     76     def release(self):
     77         self.__chip.configure(relief=RAISED)
     78 
     79 
     80 
     82 class ChipViewer:
     83     def __init__(self, switchboard, master=None):
     84         self.__sb = switchboard
     85         self.__frame = Frame(master, relief=RAISED, borderwidth=1)
     86         self.__frame.grid(row=3, column=0, ipadx=5, sticky='NSEW')
     87         # create the chip that will display the currently selected color
     88         # exactly
     89         self.__sframe = Frame(self.__frame)
     90         self.__sframe.grid(row=0, column=0)
     91         self.__selected = ChipWidget(self.__sframe, text='Selected')
     92         # create the chip that will display the nearest real X11 color
     93         # database color name
     94         self.__nframe = Frame(self.__frame)
     95         self.__nframe.grid(row=0, column=1)
     96         self.__nearest = ChipWidget(self.__nframe, text='Nearest',
     97                                     presscmd = self.__buttonpress,
     98                                     releasecmd = self.__buttonrelease)
     99 
    100     def update_yourself(self, red, green, blue):
    101         # Selected always shows the #rrggbb name of the color, nearest always
    102         # shows the name of the nearest color in the database.  BAW: should
    103         # an exact match be indicated in some way?
    104         #
    105         # Always use the #rrggbb style to actually set the color, since we may
    106         # not be using X color names (e.g. "web-safe" names)
    107         colordb = self.__sb.colordb()
    108         rgbtuple = (red, green, blue)
    109         rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple)
    110         # find the nearest
    111         nearest = colordb.nearest(red, green, blue)
    112         nearest_tuple = colordb.find_byname(nearest)
    113         nearest_rrggbb = ColorDB.triplet_to_rrggbb(nearest_tuple)
    114         self.__selected.set_color(rrggbb)
    115         self.__nearest.set_color(nearest_rrggbb)
    116         # set the name and messages areas
    117         self.__selected.set_name(rrggbb)
    118         if rrggbb == nearest_rrggbb:
    119             self.__selected.set_message(nearest)
    120         else:
    121             self.__selected.set_message('')
    122         self.__nearest.set_name(nearest_rrggbb)
    123         self.__nearest.set_message(nearest)
    124 
    125     def __buttonpress(self, event=None):
    126         self.__nearest.press()
    127 
    128     def __buttonrelease(self, event=None):
    129         self.__nearest.release()
    130         rrggbb = self.__nearest.get_color()
    131         red, green, blue = ColorDB.rrggbb_to_triplet(rrggbb)
    132         self.__sb.update_views(red, green, blue)
    133