Home | History | Annotate | Download | only in pynche
      1 """TypeinViewer class.
      2 
      3 The TypeinViewer is what you see at the lower right of the main Pynche
      4 widget.  It contains three text entry fields, one each for red, green, blue.
      5 Input into these windows is highly constrained; it only allows you to enter
      6 values that are legal for a color axis.  This usually means 0-255 for decimal
      7 input and 0x0 - 0xff for hex input.
      8 
      9 You can toggle whether you want to view and input the values in either decimal
     10 or hex by clicking on Hexadecimal.  By clicking on Update while typing, the
     11 color selection will be made on every change to the text field.  Otherwise,
     12 you must hit Return or Tab to select the color.
     13 """
     14 
     15 from Tkinter import *
     16 
     17 
     18 
     20 class TypeinViewer:
     21     def __init__(self, switchboard, master=None):
     22         # non-gui ivars
     23         self.__sb = switchboard
     24         optiondb = switchboard.optiondb()
     25         self.__hexp = BooleanVar()
     26         self.__hexp.set(optiondb.get('HEXTYPE', 0))
     27         self.__uwtyping = BooleanVar()
     28         self.__uwtyping.set(optiondb.get('UPWHILETYPE', 0))
     29         # create the gui
     30         self.__frame = Frame(master, relief=RAISED, borderwidth=1)
     31         self.__frame.grid(row=3, column=1, sticky='NSEW')
     32         # Red
     33         self.__xl = Label(self.__frame, text='Red:')
     34         self.__xl.grid(row=0, column=0, sticky=E)
     35         subframe = Frame(self.__frame)
     36         subframe.grid(row=0, column=1)
     37         self.__xox = Label(subframe, text='0x')
     38         self.__xox.grid(row=0, column=0, sticky=E)
     39         self.__xox['font'] = 'courier'
     40         self.__x = Entry(subframe, width=3)
     41         self.__x.grid(row=0, column=1)
     42         self.__x.bindtags(self.__x.bindtags() + ('Normalize', 'Update'))
     43         self.__x.bind_class('Normalize', '<Key>', self.__normalize)
     44         self.__x.bind_class('Update'   , '<Key>', self.__maybeupdate)
     45         # Green
     46         self.__yl = Label(self.__frame, text='Green:')
     47         self.__yl.grid(row=1, column=0, sticky=E)
     48         subframe = Frame(self.__frame)
     49         subframe.grid(row=1, column=1)
     50         self.__yox = Label(subframe, text='0x')
     51         self.__yox.grid(row=0, column=0, sticky=E)
     52         self.__yox['font'] = 'courier'
     53         self.__y = Entry(subframe, width=3)
     54         self.__y.grid(row=0, column=1)
     55         self.__y.bindtags(self.__y.bindtags() + ('Normalize', 'Update'))
     56         # Blue
     57         self.__zl = Label(self.__frame, text='Blue:')
     58         self.__zl.grid(row=2, column=0, sticky=E)
     59         subframe = Frame(self.__frame)
     60         subframe.grid(row=2, column=1)
     61         self.__zox = Label(subframe, text='0x')
     62         self.__zox.grid(row=0, column=0, sticky=E)
     63         self.__zox['font'] = 'courier'
     64         self.__z = Entry(subframe, width=3)
     65         self.__z.grid(row=0, column=1)
     66         self.__z.bindtags(self.__z.bindtags() + ('Normalize', 'Update'))
     67         # Update while typing?
     68         self.__uwt = Checkbutton(self.__frame,
     69                                  text='Update while typing',
     70                                  variable=self.__uwtyping)
     71         self.__uwt.grid(row=3, column=0, columnspan=2, sticky=W)
     72         # Hex/Dec
     73         self.__hex = Checkbutton(self.__frame,
     74                                  text='Hexadecimal',
     75                                  variable=self.__hexp,
     76                                  command=self.__togglehex)
     77         self.__hex.grid(row=4, column=0, columnspan=2, sticky=W)
     78 
     79     def __togglehex(self, event=None):
     80         red, green, blue = self.__sb.current_rgb()
     81         if self.__hexp.get():
     82             label = '0x'
     83         else:
     84             label = '  '
     85         self.__xox['text'] = label
     86         self.__yox['text'] = label
     87         self.__zox['text'] = label
     88         self.update_yourself(red, green, blue)
     89 
     90     def __normalize(self, event=None):
     91         ew = event.widget
     92         contents = ew.get()
     93         icursor = ew.index(INSERT)
     94         if contents and contents[0] in 'xX' and self.__hexp.get():
     95             contents = '0' + contents
     96         # Figure out the contents in the current base.
     97         try:
     98             if self.__hexp.get():
     99                 v = int(contents, 16)
    100             else:
    101                 v = int(contents)
    102         except ValueError:
    103             v = None
    104         # If value is not legal, or empty, delete the last character inserted
    105         # and ring the bell.  Don't ring the bell if the field is empty (it'll
    106         # just equal zero.
    107         if v is None:
    108             pass
    109         elif v < 0 or v > 255:
    110             i = ew.index(INSERT)
    111             if event.char:
    112                 contents = contents[:i-1] + contents[i:]
    113                 icursor -= 1
    114             ew.bell()
    115         elif self.__hexp.get():
    116             contents = hex(v)[2:]
    117         else:
    118             contents = int(v)
    119         ew.delete(0, END)
    120         ew.insert(0, contents)
    121         ew.icursor(icursor)
    122 
    123     def __maybeupdate(self, event=None):
    124         if self.__uwtyping.get() or event.keysym in ('Return', 'Tab'):
    125             self.__update(event)
    126 
    127     def __update(self, event=None):
    128         redstr = self.__x.get() or '0'
    129         greenstr = self.__y.get() or '0'
    130         bluestr = self.__z.get() or '0'
    131         if self.__hexp.get():
    132             base = 16
    133         else:
    134             base = 10
    135         red, green, blue = [int(x, base) for x in (redstr, greenstr, bluestr)]
    136         self.__sb.update_views(red, green, blue)
    137 
    138     def update_yourself(self, red, green, blue):
    139         if self.__hexp.get():
    140             sred, sgreen, sblue = [hex(x)[2:] for x in (red, green, blue)]
    141         else:
    142             sred, sgreen, sblue = red, green, blue
    143         x, y, z = self.__x, self.__y, self.__z
    144         xicursor = x.index(INSERT)
    145         yicursor = y.index(INSERT)
    146         zicursor = z.index(INSERT)
    147         x.delete(0, END)
    148         y.delete(0, END)
    149         z.delete(0, END)
    150         x.insert(0, sred)
    151         y.insert(0, sgreen)
    152         z.insert(0, sblue)
    153         x.icursor(xicursor)
    154         y.icursor(yicursor)
    155         z.icursor(zicursor)
    156 
    157     def hexp_var(self):
    158         return self.__hexp
    159 
    160     def save_options(self, optiondb):
    161         optiondb['HEXTYPE'] = self.__hexp.get()
    162         optiondb['UPWHILETYPE'] = self.__uwtyping.get()
    163