/Tools/pynche/TypeinViewer.py

http://unladen-swallow.googlecode.com/ · Python · 161 lines · 127 code · 10 blank · 24 comment · 26 complexity · 147917dc65f67834d11d0036bcca7d0d MD5 · raw file

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