home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / webclean / !!!python!!! / BeOpen-Python-2.0.exe / LISTVIEWER.PY < prev    next >
Encoding:
Python Source  |  2000-09-28  |  6.7 KB  |  177 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. ADDTOVIEW = 'Color %List Window...'
  22.  
  23. class ListViewer:
  24.     def __init__(self, switchboard, master=None):
  25.         self.__sb = switchboard
  26.         optiondb = switchboard.optiondb()
  27.         self.__lastbox = None
  28.         self.__dontcenter = 0
  29.         # GUI
  30.         root = self.__root = Toplevel(master, class_='Pynche')
  31.         root.protocol('WM_DELETE_WINDOW', self.withdraw)
  32.         root.title('Pynche Color List')
  33.         root.iconname('Pynche Color List')
  34.         root.bind('<Alt-q>', self.__quit)
  35.         root.bind('<Alt-Q>', self.__quit)
  36.         root.bind('<Alt-w>', self.withdraw)
  37.         root.bind('<Alt-W>', self.withdraw)
  38.         #
  39.         # create the canvas which holds everything, and its scrollbar
  40.         #
  41.         frame = self.__frame = Frame(root)
  42.         frame.pack()
  43.         canvas = self.__canvas = Canvas(frame, width=160, height=300,
  44.                                         borderwidth=2, relief=SUNKEN)
  45.         self.__scrollbar = Scrollbar(frame)
  46.         self.__scrollbar.pack(fill=Y, side=RIGHT)
  47.         canvas.pack(fill=BOTH, expand=1)
  48.         canvas.configure(yscrollcommand=(self.__scrollbar, 'set'))
  49.         self.__scrollbar.configure(command=(canvas, 'yview'))
  50.         self.__populate()
  51.         #
  52.         # Update on click
  53.         self.__uoc = BooleanVar()
  54.         self.__uoc.set(optiondb.get('UPONCLICK', 1))
  55.         self.__uocbtn = Checkbutton(root,
  56.                                     text='Update on Click',
  57.                                     variable=self.__uoc,
  58.                                     command=self.__toggleupdate)
  59.         self.__uocbtn.pack(expand=1, fill=BOTH)
  60.         #
  61.         # alias list
  62.         self.__alabel = Label(root, text='Aliases:')
  63.         self.__alabel.pack()
  64.         self.__aliases = Listbox(root, height=5,
  65.                                  selectmode=BROWSE)
  66.         self.__aliases.pack(expand=1, fill=BOTH)
  67.  
  68.     def __populate(self):
  69.         #
  70.         # create all the buttons
  71.         colordb = self.__sb.colordb()
  72.         canvas = self.__canvas
  73.         row = 0
  74.         widest = 0
  75.         bboxes = self.__bboxes = []
  76.         for name in colordb.unique_names():
  77.             exactcolor = ColorDB.triplet_to_rrggbb(colordb.find_byname(name))
  78.             canvas.create_rectangle(5, row*20 + 5,
  79.                                     20, row*20 + 20,
  80.                                     fill=exactcolor)
  81.             textid = canvas.create_text(25, row*20 + 13,
  82.                                         text=name,
  83.                                         anchor=W)
  84.             x1, y1, textend, y2 = canvas.bbox(textid)
  85.             boxid = canvas.create_rectangle(3, row*20+3,
  86.                                             textend+3, row*20 + 23,
  87.                                             outline='',
  88.                                             tags=(exactcolor, 'all'))
  89.             canvas.bind('<ButtonRelease>', self.__onrelease)
  90.             bboxes.append(boxid)
  91.             if textend+3 > widest:
  92.                 widest = textend+3
  93.             row = row + 1
  94.         canvheight = (row-1)*20 + 25
  95.         canvas.config(scrollregion=(0, 0, 150, canvheight))
  96.         for box in bboxes:
  97.             x1, y1, x2, y2 = canvas.coords(box)
  98.             canvas.coords(box, x1, y1, widest, y2)
  99.  
  100.     def __onrelease(self, event=None):
  101.         canvas = self.__canvas
  102.         # find the current box
  103.         x = canvas.canvasx(event.x)
  104.         y = canvas.canvasy(event.y)
  105.         ids = canvas.find_overlapping(x, y, x, y)
  106.         for boxid in ids:
  107.             if boxid in self.__bboxes:
  108.                 break
  109.         else:
  110. ##            print 'No box found!'
  111.             return
  112.         tags = self.__canvas.gettags(boxid)
  113.         for t in tags:
  114.             if t[0] == '#':
  115.                 break
  116.         else:
  117. ##            print 'No color tag found!'
  118.             return
  119.         red, green, blue = ColorDB.rrggbb_to_triplet(t)
  120.         self.__dontcenter = 1
  121.         if self.__uoc.get():
  122.             self.__sb.update_views(red, green, blue)
  123.         else:
  124.             self.update_yourself(red, green, blue)
  125.             self.__red, self.__green, self.__blue = red, green, blue
  126.  
  127.     def __toggleupdate(self, event=None):
  128.         if self.__uoc.get():
  129.             self.__sb.update_views(self.__red, self.__green, self.__blue)
  130.  
  131.     def __quit(self, event=None):
  132.         self.__root.quit()
  133.  
  134.     def withdraw(self, event=None):
  135.         self.__root.withdraw()
  136.  
  137.     def deiconify(self, event=None):
  138.         self.__root.deiconify()
  139.  
  140.     def update_yourself(self, red, green, blue):
  141.         canvas = self.__canvas
  142.         # turn off the last box
  143.         if self.__lastbox:
  144.             canvas.itemconfigure(self.__lastbox, outline='')
  145.         # turn on the current box
  146.         colortag = ColorDB.triplet_to_rrggbb((red, green, blue))
  147.         canvas.itemconfigure(colortag, outline='black')
  148.         self.__lastbox = colortag
  149.         # fill the aliases
  150.         self.__aliases.delete(0, END)
  151.         try:
  152.             aliases = self.__sb.colordb().aliases_of(red, green, blue)[1:]
  153.         except ColorDB.BadColor:
  154.             self.__aliases.insert(END, '<no matching color>')
  155.             return
  156.         if not aliases:
  157.             self.__aliases.insert(END, '<no aliases>')
  158.         else:
  159.             for name in aliases:
  160.                 self.__aliases.insert(END, name)
  161.         # maybe scroll the canvas so that the item is visible
  162.         if self.__dontcenter:
  163.             self.__dontcenter = 0
  164.         else:
  165.             height = canvas['height']
  166.             ig, ig, ig, y1 = canvas.coords(colortag)
  167.             ig, ig, ig, y2 = canvas.coords(self.__bboxes[-1])
  168.             h = int(canvas['height']) * 0.5
  169.             canvas.yview('moveto', (y1-h) / y2)
  170.  
  171.     def save_options(self, optiondb):
  172.         optiondb['UPONCLICK'] = self.__uoc.get()
  173.  
  174.     def colordb_changed(self, colordb):
  175.         self.__canvas.delete('all')
  176.         self.__populate()
  177.