home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Tools / pynche / ListViewer.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  6.3 KB  |  167 lines

  1. """ListViewer class.
  2.  
  3. This class implements an input/output view on the color model.  It lists every
  4. unique color (e.g. unique r/g/b value) found in the color database.  Each
  5. color is shown by small swatch and primary color name.  Some colors have
  6. aliases -- more than one name for the same r/g/b value.  These aliases are
  7. displayed in the small listbox at the bottom of the screen.
  8.  
  9. Clicking on a color name or swatch selects that color and updates all other
  10. windows.  When a color is selected in a different viewer, the color list is
  11. scrolled to the selected color and it is highlighted.  If the selected color
  12. is an r/g/b value without a name, no scrolling occurs.
  13.  
  14. You can turn off Update On Click if all you want to see is the alias for a
  15. given name, without selecting the color.
  16. """
  17.  
  18. from Tkinter import *
  19. import ColorDB
  20.  
  21. class ListViewer:
  22.     def __init__(self, switchboard, master=None):
  23.         self.__sb = switchboard
  24.         optiondb = switchboard.optiondb()
  25.         self.__lastbox = None
  26.         self.__dontcenter = 0
  27.         # GUI
  28.         root = self.__root = Toplevel(master, class_='Pynche')
  29.         root.protocol('WM_DELETE_WINDOW', self.withdraw)
  30.         root.title('Pynche Color List')
  31.         root.iconname('Pynche Color List')
  32.         root.bind('<Alt-q>', self.__quit)
  33.         root.bind('<Alt-Q>', self.__quit)
  34.         root.bind('<Alt-w>', self.withdraw)
  35.         root.bind('<Alt-W>', self.withdraw)
  36.         #
  37.         # create the canvas which holds everything, and its scrollbar
  38.         #
  39.         frame = self.__frame = Frame(root)
  40.         frame.pack()
  41.         canvas = self.__canvas = Canvas(frame, width=160, height=300,
  42.                                         borderwidth=2, relief=SUNKEN)
  43.         self.__scrollbar = Scrollbar(frame)
  44.         self.__scrollbar.pack(fill=Y, side=RIGHT)
  45.         canvas.pack(fill=BOTH, expand=1)
  46.         canvas.configure(yscrollcommand=(self.__scrollbar, 'set'))
  47.         self.__scrollbar.configure(command=(canvas, 'yview'))
  48.         #
  49.         # create all the buttons
  50.         colordb = switchboard.colordb()
  51.         row = 0
  52.         widest = 0
  53.         bboxes = self.__bboxes = []
  54.         for name in colordb.unique_names():
  55.             exactcolor = ColorDB.triplet_to_rrggbb(colordb.find_byname(name))
  56.             canvas.create_rectangle(5, row*20 + 5,
  57.                                     20, row*20 + 20,
  58.                                     fill=exactcolor)
  59.             textid = canvas.create_text(25, row*20 + 13,
  60.                                         text=name,
  61.                                         anchor=W)
  62.             x1, y1, textend, y2 = canvas.bbox(textid)
  63.             boxid = canvas.create_rectangle(3, row*20+3,
  64.                                             textend+3, row*20 + 23,
  65.                                             outline='',
  66.                                             tags=(exactcolor,))
  67.             canvas.bind('<ButtonRelease>', self.__onrelease)
  68.             bboxes.append(boxid)
  69.             if textend+3 > widest:
  70.                 widest = textend+3
  71.             row = row + 1
  72.         canvheight = (row-1)*20 + 25
  73.         canvas.config(scrollregion=(0, 0, 150, canvheight))
  74.         for box in bboxes:
  75.             x1, y1, x2, y2 = canvas.coords(box)
  76.             canvas.coords(box, x1, y1, widest, y2)
  77.         #
  78.         # Update on click
  79.         self.__uoc = BooleanVar()
  80.         self.__uoc.set(optiondb.get('UPONCLICK', 1))
  81.         self.__uocbtn = Checkbutton(root,
  82.                                     text='Update on Click',
  83.                                     variable=self.__uoc,
  84.                                     command=self.__toggleupdate)
  85.         self.__uocbtn.pack(expand=1, fill=BOTH)
  86.         #
  87.         # alias list
  88.         self.__alabel = Label(root, text='Aliases:')
  89.         self.__alabel.pack()
  90.         self.__aliases = Listbox(root, height=5,
  91.                                  selectmode=BROWSE)
  92.         self.__aliases.pack(expand=1, fill=BOTH)
  93.  
  94.     def __onrelease(self, event=None):
  95.         canvas = self.__canvas
  96.         # find the current box
  97.         x = canvas.canvasx(event.x)
  98.         y = canvas.canvasy(event.y)
  99.         ids = canvas.find_overlapping(x, y, x, y)
  100.         for boxid in ids:
  101.             if boxid in self.__bboxes:
  102.                 break
  103.         else:
  104. ##            print 'No box found!'
  105.             return
  106.         tags = self.__canvas.gettags(boxid)
  107.         for t in tags:
  108.             if t[0] == '#':
  109.                 break
  110.         else:
  111. ##            print 'No color tag found!'
  112.             return
  113.         red, green, blue = ColorDB.rrggbb_to_triplet(t)
  114.         self.__dontcenter = 1
  115.         if self.__uoc.get():
  116.             self.__sb.update_views(red, green, blue)
  117.         else:
  118.             self.update_yourself(red, green, blue)
  119.             self.__red, self.__green, self.__blue = red, green, blue
  120.  
  121.     def __toggleupdate(self, event=None):
  122.         if self.__uoc.get():
  123.             self.__sb.update_views(self.__red, self.__green, self.__blue)
  124.  
  125.     def __quit(self, event=None):
  126.         self.__root.quit()
  127.  
  128.     def withdraw(self, event=None):
  129.         self.__root.withdraw()
  130.  
  131.     def deiconify(self, event=None):
  132.         self.__root.deiconify()
  133.  
  134.     def update_yourself(self, red, green, blue):
  135.         canvas = self.__canvas
  136.         # turn off the last box
  137.         if self.__lastbox:
  138.             canvas.itemconfigure(self.__lastbox, outline='')
  139.         # turn on the current box
  140.         colortag = ColorDB.triplet_to_rrggbb((red, green, blue))
  141.         canvas.itemconfigure(colortag, outline='black')
  142.         self.__lastbox = colortag
  143.         # fill the aliases
  144.         self.__aliases.delete(0, END)
  145.         try:
  146.             aliases = self.__sb.colordb().aliases_of(red, green, blue)[1:]
  147.         except ColorDB.BadColor:
  148.             self.__aliases.insert(END, '<no matching color>')
  149.             return
  150.         if not aliases:
  151.             self.__aliases.insert(END, '<no aliases>')
  152.         else:
  153.             for name in aliases:
  154.                 self.__aliases.insert(END, name)
  155.         # maybe scroll the canvas so that the item is visible
  156.         if self.__dontcenter:
  157.             self.__dontcenter = 0
  158.         else:
  159.             height = canvas['height']
  160.             ig, ig, ig, y1 = canvas.coords(colortag)
  161.             ig, ig, ig, y2 = canvas.coords(self.__bboxes[-1])
  162.             h = int(canvas['height']) * 0.5
  163.             canvas.yview('moveto', (y1-h) / y2)
  164.  
  165.     def save_options(self, optiondb):
  166.         optiondb['UPONCLICK'] = self.__uoc.get()
  167.