TypeinViewer.py 5.96 KB
Newer Older
Barry Warsaw's avatar
Barry Warsaw committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
"""TypeinViewer class.

The TypeinViewer is what you see at the lower right of the main Pynche
widget.  It contains three text entry fields, one each for red, green, blue.
Input into these windows is highly constrained; it only allows you to enter
values that are legal for a color axis.  This usually means 0-255 for decimal
input and 0x0 - 0xff for hex input.

You can toggle whether you want to view and input the values in either decimal
or hex by clicking on Hexadecimal.  By clicking on Update while typing, the
color selection will be made on every change to the text field.  Otherwise,
you must hit Return or Tab to select the color.
"""

15
from tkinter import *
16

Barry Warsaw's avatar
Barry Warsaw committed
17

18

19
class TypeinViewer:
20
    def __init__(self, switchboard, master=None):
Barry Warsaw's avatar
Barry Warsaw committed
21 22
        # non-gui ivars
        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))
Barry Warsaw's avatar
Barry Warsaw committed
28
        # create the gui
29
        self.__frame = Frame(master, relief=RAISED, borderwidth=1)
30
        self.__frame.grid(row=3, column=1, sticky='NSEW')
Barry Warsaw's avatar
Barry Warsaw committed
31 32 33
        # Red
        self.__xl = Label(self.__frame, text='Red:')
        self.__xl.grid(row=0, column=0, sticky=E)
34 35 36 37 38 39
        subframe = Frame(self.__frame)
        subframe.grid(row=0, column=1)
        self.__xox = Label(subframe, text='0x')
        self.__xox.grid(row=0, column=0, sticky=E)
        self.__xox['font'] = 'courier'
        self.__x = Entry(subframe, width=3)
Barry Warsaw's avatar
Barry Warsaw committed
40 41 42
        self.__x.grid(row=0, column=1)
        self.__x.bindtags(self.__x.bindtags() + ('Normalize', 'Update'))
        self.__x.bind_class('Normalize', '<Key>', self.__normalize)
43
        self.__x.bind_class('Update'   , '<Key>', self.__maybeupdate)
Barry Warsaw's avatar
Barry Warsaw committed
44 45 46
        # Green
        self.__yl = Label(self.__frame, text='Green:')
        self.__yl.grid(row=1, column=0, sticky=E)
47 48 49 50 51 52 53
        subframe = Frame(self.__frame)
        subframe.grid(row=1, column=1)
        self.__yox = Label(subframe, text='0x')
        self.__yox.grid(row=0, column=0, sticky=E)
        self.__yox['font'] = 'courier'
        self.__y = Entry(subframe, width=3)
        self.__y.grid(row=0, column=1)
Barry Warsaw's avatar
Barry Warsaw committed
54 55 56 57
        self.__y.bindtags(self.__y.bindtags() + ('Normalize', 'Update'))
        # Blue
        self.__zl = Label(self.__frame, text='Blue:')
        self.__zl.grid(row=2, column=0, sticky=E)
58 59 60 61 62 63 64
        subframe = Frame(self.__frame)
        subframe.grid(row=2, column=1)
        self.__zox = Label(subframe, text='0x')
        self.__zox.grid(row=0, column=0, sticky=E)
        self.__zox['font'] = 'courier'
        self.__z = Entry(subframe, width=3)
        self.__z.grid(row=0, column=1)
Barry Warsaw's avatar
Barry Warsaw committed
65
        self.__z.bindtags(self.__z.bindtags() + ('Normalize', 'Update'))
66 67 68 69 70 71 72 73
        # Update while typing?
        self.__uwt = Checkbutton(self.__frame,
                                 text='Update while typing',
                                 variable=self.__uwtyping)
        self.__uwt.grid(row=3, column=0, columnspan=2, sticky=W)
        # Hex/Dec
        self.__hex = Checkbutton(self.__frame,
                                 text='Hexadecimal',
74 75
                                 variable=self.__hexp,
                                 command=self.__togglehex)
76
        self.__hex.grid(row=4, column=0, columnspan=2, sticky=W)
Barry Warsaw's avatar
Barry Warsaw committed
77

78
    def __togglehex(self, event=None):
Barry Warsaw's avatar
Barry Warsaw committed
79
        red, green, blue = self.__sb.current_rgb()
80 81 82 83 84 85 86
        if self.__hexp.get():
            label = '0x'
        else:
            label = '  '
        self.__xox['text'] = label
        self.__yox['text'] = label
        self.__zox['text'] = label
Barry Warsaw's avatar
Barry Warsaw committed
87
        self.update_yourself(red, green, blue)
88

Barry Warsaw's avatar
Barry Warsaw committed
89 90 91
    def __normalize(self, event=None):
        ew = event.widget
        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.
Barry Warsaw's avatar
Barry Warsaw committed
96
        try:
97
            if self.__hexp.get():
98
                v = int(contents, 16)
Barry Warsaw's avatar
Barry Warsaw committed
99
            else:
100
                v = int(contents)
Barry Warsaw's avatar
Barry Warsaw committed
101 102
        except ValueError:
            v = None
103 104 105 106 107 108
        # If value is not legal, or empty, delete the last character inserted
        # and ring the bell.  Don't ring the bell if the field is empty (it'll
        # just equal zero.
        if v is None:
            pass
        elif v < 0 or v > 255:
109
            i = ew.index(INSERT)
110 111
            if event.char:
                contents = contents[:i-1] + contents[i:]
112
                icursor -= 1
Barry Warsaw's avatar
Barry Warsaw committed
113
            ew.bell()
114
        elif self.__hexp.get():
115
            contents = hex(v)[2:]
Barry Warsaw's avatar
Barry Warsaw committed
116 117 118 119
        else:
            contents = int(v)
        ew.delete(0, END)
        ew.insert(0, contents)
120
        ew.icursor(icursor)
Barry Warsaw's avatar
Barry Warsaw committed
121

122
    def __maybeupdate(self, event=None):
123
        if self.__uwtyping.get() or event.keysym in ('Return', 'Tab'):
124 125
            self.__update(event)

Barry Warsaw's avatar
Barry Warsaw committed
126
    def __update(self, event=None):
127 128 129
        redstr = self.__x.get() or '0'
        greenstr = self.__y.get() or '0'
        bluestr = self.__z.get() or '0'
130
        if self.__hexp.get():
131
            base = 16
Barry Warsaw's avatar
Barry Warsaw committed
132
        else:
133 134
            base = 10
        red, green, blue = [int(x, base) for x in (redstr, greenstr, bluestr)]
Barry Warsaw's avatar
Barry Warsaw committed
135
        self.__sb.update_views(red, green, blue)
Barry Warsaw's avatar
Barry Warsaw committed
136

Barry Warsaw's avatar
Barry Warsaw committed
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)]
Barry Warsaw's avatar
Barry Warsaw committed
140
        else:
141
            sred, sgreen, sblue = red, green, blue
142 143 144 145 146 147 148
        x, y, z = self.__x, self.__y, self.__z
        xicursor = x.index(INSERT)
        yicursor = y.index(INSERT)
        zicursor = z.index(INSERT)
        x.delete(0, END)
        y.delete(0, END)
        z.delete(0, END)
149 150 151
        x.insert(0, sred)
        y.insert(0, sgreen)
        z.insert(0, sblue)
152 153 154
        x.icursor(xicursor)
        y.icursor(yicursor)
        z.icursor(zicursor)
Barry Warsaw's avatar
Barry Warsaw committed
155

Barry Warsaw's avatar
Barry Warsaw committed
156 157
    def hexp_var(self):
        return self.__hexp
158 159 160 161

    def save_options(self, optiondb):
        optiondb['HEXTYPE'] = self.__hexp.get()
        optiondb['UPWHILETYPE'] = self.__uwtyping.get()