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