Package mglutil :: Package gui :: Package BasicWidgets :: Package Tk :: Module colorWidgets
[hide private]
[frames] | no frames]

Source Code for Module mglutil.gui.BasicWidgets.Tk.colorWidgets

  1  ############################################################################# 
  2  # 
  3  # Author: Sophie COON, Michel F. SANNER 
  4  # 
  5  # Copyright: M. Sanner TSRI 2000 
  6  # 
  7  ############################################################################# 
  8   
  9  #$Header: /opt/cvs/python/packages/share1.5/mglutil/gui/BasicWidgets/Tk/colorWidgets.py,v 1.13 2007/01/25 17:09:27 rhuey Exp $ 
 10  # 
 11  #$Id: colorWidgets.py,v 1.13 2007/01/25 17:09:27 rhuey Exp $ 
 12  # 
 13   
 14  import Tkinter, Pmw, Numeric, os 
 15   
 16  from types import ListType, TupleType 
 17  from mglutil.util.callback import CallBackFunction, CallbackManager 
 18  from mglutil.util.colorUtil import ToRGB, ToHSV, ToHEX 
 19  from mglutil.gui.InputForm.Tk.gui import InputFormDescr,InputForm,evalString 
 20  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ExtendedSliderWidget 
 21  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser 
 22  from mglutil.gui.BasicWidgets.Tk.fileBrowsers import fileOpenAsk, fileSaveAsk 
 23  import tkMessageBox 
 24  import os, math 
 25   
26 -class ColorWheel:
27 - def __init__(self, master, title=None, callback=None, immediate=1):
28 if not master: 29 master = Tkinter.Toplevel() 30 31 if title is not None: 32 master.title(title) 33 34 f = self.frame = Tkinter.Frame(master) 35 path = __import__('mglutil').__path__ 36 iconfile = os.path.join(path[0],'gui/BasicWidgets/Tk/cw.ppm') 37 self.iconfile = iconfile 38 self.cwim = Tkinter.PhotoImage(file=iconfile) 39 self.width = self.cwim.width() 40 self.height = self.cwim.height() 41 self.cwcanvas = Tkinter.Canvas(f, width=self.width, 42 height=self.height, ###relief='sunken', 43 borderwidth=3 ) 44 self.cwcanvas.create_image(3, 3, anchor=Tkinter.NW, image=self.cwim) 45 self.cwcanvas.pack() 46 self.frame.pack() 47 48 #self.callback = None 49 self.cbManager = CallbackManager() 50 if callback: 51 if type(callback) in [ListType, TupleType]: 52 map(self.cbManager.AddCallback, callback) 53 else: 54 self.cbManager.AddCallback(callback) 55 self.afterID = None 56 self.immediate = immediate 57 self.x = 0 58 self.y = 0 59 self.radius = 55 60 cx = self.cx = self.width/2 + 3 61 cy = self.cy = self.height/2 + 3 62 63 self.cursor = self.cwcanvas.create_line( 64 65 cx-3, cy-3, cx-3, cy+3, cx+3,cy+3, cx+3, cy-3, cx-3, cy-3 ) 66 67 self.hsvColor = [1.,1.,1.] 68 69 self.cwcanvas.bind('<ButtonPress-1>', self.mouse1Down)
70 #self.cursor = self.cwcanvas.create_line(cx, cy, cx-55, cy) 71 72
73 - def _MoveCursor(self, x, y, trigger=1):
74 # find the saturation based on distance 75 s = math.sqrt(x*x + y*y) / self.radius 76 if s > 1.0: 77 x = x / s 78 y = y / s 79 s = 1.0 80 81 # now find the hue based on the angle 82 if x or y: 83 angle = math.atan2(y, x) 84 if angle < 0.0: 85 angle = angle + (2.*math.pi) 86 h = 1. - angle / (2.0 * math.pi) 87 else: 88 h = 0 89 # check if redraw and callback are needed 90 if self.hsvColor[0] != h or self.hsvColor[1] != s: 91 if trigger==1: 92 self.hsvColor[0] = h 93 self.hsvColor[1] = s 94 cx = self.cx+x 95 cy = self.cy+y 96 self.cwcanvas.coords( self.cursor, cx-3, cy-3, cx-3, cy+3, 97 cx+3,cy+3, cx+3, cy-3, cx-3, cy-3 ) 98 99 if self.cbManager.callbacks: 100 self.cbManager.CallCallbacks(self.get('RGB'))
101
102 - def mouse1Down(self, event=None):
103 self.cwcanvas.bind('<B1-Motion>', self.mouse1Move) 104 self.cwcanvas.bind('<ButtonRelease-1>', self.mouse1Up) 105 self._MoveCursor(event.x - self.cx, event.y - self.cy)
106 107
108 - def mouse1Move(self, event=None):
109 if self.immediate: 110 if self.afterID is not None: 111 self.cwcanvas.after_cancel(self.afterID) 112 self.afterID = None 113 else: 114 self.afterID = self.cwcanvas.after(15,self._MoveCursor , 115 event.x - self.cx, 116 event.y - self.cy) 117 118 else: 119 self._MoveCursor(event.x - self.cx, event.y - self.cy, 120 trigger=0)
121 122
123 - def mouse1Up(self, event=None):
124 self._MoveCursor(event.x - self.cx, event.y - self.cy) 125 self.cwcanvas.unbind('<B1-Motion>') 126 self.cwcanvas.unbind('<ButtonRelease-1>')
127 128
129 - def get(self, mode='HSV'):
130 """Get the current color""" 131 if mode == 'RGB': 132 rgb = ToRGB(self.hsvColor) 133 #return OneColor(rgb) 134 return rgb 135 136 elif mode == 'HSV': 137 #return OneColor(self.hsvColor) 138 return self.hsvColor 139 140 elif mode == 'HEX': 141 col = Numeric.array(ToRGB(self.hsvColor[:]), 'f') * 255 142 return ToHEX(col)
143 144
145 - def set(self, color, mode='HSV', trigger=1):
146 """Set the current color""" 147 assert len(color)==3 148 #color = OneColor(color) 149 if mode=='RGB': color = ToHSV(color[:]) 150 self.hsvColor = list(color[:]) 151 152 # update cursor 153 rad = self.hsvColor[1] * self.radius 154 angle = 2.0 * math.pi * (1. - self.hsvColor[0]) 155 cx = self.cx + int(rad * math.cos(angle)) 156 cy = self.cy + int(rad * math.sin(angle)) 157 self.cwcanvas.coords( self.cursor, cx-3, cy-3, cx-3, cy+3, 158 cx+3,cy+3, cx+3, cy-3, cx-3, cy-3 ) 159 160 if trigger==1 and self.immediate and self.cbManager.callbacks: 161 self.cbManager.CallCallbacks(self.get('RGB'))
162 163
164 -class ColorEditor:
165 """ 166 The ColorEditor is a widget providing a colorwheel, a value scale, 167 HSV entries, RGB entries and HEX(HexTriplet) entries 168 """
169 - def __init__(self, master=None, currentColor=(1.0,1.0,1.0), mode='RGB', 170 commands = None, immediate=1):
171 assert mode in ['RGB', 'HSV','HEX'] 172 self.mode = mode 173 if not master: 174 self.master = Tkinter.Toplevel() 175 else: 176 self.master = master 177 self.afterID = None 178 self.immediate = immediate 179 # The editFrame is the main Frame of the widget 180 self.editFrame = Tkinter.Frame(self.master, borderwidth=2, 181 relief='ridge') 182 self.cbManager = CallbackManager() 183 if commands: 184 if type(commands) in [ListType, TupleType]: 185 map(self.cbManager.AddCallback, commands) 186 else: 187 self.cbManager.AddCallback(commands) 188 189 if mode == 'HSV': 190 self.currentHSV = list(currentColor) 191 self.currentRGB = list(ToRGB(currentColor)) 192 self.currentHEX = ToHEX(currentColor, mode = 'HSV') 193 194 elif mode == 'RGB': 195 self.currentRGB = list(currentColor) 196 self.currentHSV = list(ToHSV(currentColor)) 197 self.currentHEX = ToHEX(currentColor, mode='RGB') 198 199 elif mode == 'HEX': 200 self.currentRGB = ToHEX(currentColor, mode='RGB') 201 self.currentHSV = ToHEX(currentColor, mode='HSV') 202 self.currentHEX = currentColor 203 else: 204 print 'mode not recognized mode set to RGB' 205 self.createColorEditor()
206
207 - def createColorEditor(self):
208 # The chooserFrame containinsg the colorwheel and the value scale 209 chooserFrame = Tkinter.Frame(self.editFrame) 210 # Create a Tkinter Scale widget bound a callback : self.scale_cb 211 self.vScale = Tkinter.Scale(chooserFrame, 212 from_ = 1.0, to_ = 0.0, 213 orient='vertical', resolution=0.01,) 214 ## command = self.scale_cb) 215 if self.immediate: 216 self.vScale.configure(command=self.scale_cb) 217 else: 218 self.vScale.bind('<ButtonRelease-1>', self.scaleUp_cb) 219 220 221 222 223 224 # pack the scale to be on the left side of the colorwheel 225 self.vScale.pack(side='right', padx=5, pady=5, expand=1, 226 fill='both') 227 self.vScale.set(1.0) 228 229 # Create the colorWheel Frame 230 wheelFrame = Tkinter.Frame(chooserFrame, relief='ridge', 231 borderwidth=1) 232 # Pack the ColorWheel 233 wheelFrame.pack(side='left',pady=5, padx=10,fill='both', 234 expand = 1) 235 # Create the ColorWheel 236 237 238 # to silent an error report from pychecker 239 self.cw = ColorWheel(wheelFrame,None,self.colorWidget_cb,self.immediate) 240 #self.cw = ColorWheel(wheelFrame,title=None, 241 # callback=self.colorWidget_cb, 242 # immediate=self.immediate) 243 244 245 self.cw.set(self.currentRGB, mode='RGB', trigger=0) 246 # Bind the colorwidget to a callback function self.colorWidget_cb 247 #self.cw.callback = self.colorWidget_cb 248 # Pack the chooserFrame 249 chooserFrame.pack(expand=1,fill='both') 250 251 bottomFrame = Tkinter.Frame(self.editFrame) 252 #The preview frame will contain the frame to show the choosen color 253 previewFrame = Tkinter.Frame(bottomFrame) 254 previewFrame.pack(side='left', fill='both', expand=1) 255 preview = Tkinter.Frame(previewFrame,) 256 bg = self.currentHEX 257 self.chip = Tkinter.Frame(previewFrame, 258 borderwidth=3, width=50, 259 height=30, bg=bg, relief='ridge') 260 # Pack the chipFrame 261 self.chip.pack(fill='both', expand = 1) 262 263 264 #The entriesFrame will contain all the entryFields 265 entriesFrame = Tkinter.Frame(bottomFrame) 266 entriesOption = {'labelpos':'w', 267 'validate':{'validator':'real', 268 'min':0.0, 'max':1.0}, 269 'entry_width':4, 270 } 271 272 # the hsvFrame will contain the H,S,V entryFields 273 hsvFrame = Tkinter.Frame(entriesFrame) 274 275 entriesOption['label_text'] = 'H' 276 entriesOption['value'] = "%4.2f"%self.currentHSV[0] 277 entriesOption['command'] = self.hVal_cb 278 self.hVal = apply(Pmw.EntryField, (hsvFrame,), entriesOption) 279 self.hVal.pack(side = 'left') 280 281 entriesOption['label_text'] = 'S' 282 entriesOption['value'] = "%4.2f"%self.currentHSV[1] 283 entriesOption['command'] = self.sVal_cb 284 self.sVal = apply(Pmw.EntryField, (hsvFrame,), entriesOption) 285 self.sVal.pack(side = 'left') 286 287 entriesOption['label_text'] = 'V' 288 entriesOption['value'] = "%4.2f"%self.currentHSV[2] 289 entriesOption['command'] = self.vVal_cb 290 self.vVal= apply(Pmw.EntryField, (hsvFrame,), entriesOption) 291 self.vVal.pack(side = 'left') 292 293 hsvFrame.pack(padx=4, pady=4,fill='both',expand=1) 294 295 rgbFrame = Tkinter.Frame(entriesFrame) 296 # RGB entries 297 entriesOption['label_text'] = 'R' 298 entriesOption['value'] = "%4.2f"%self.currentRGB[0] 299 entriesOption['command'] = self.rVal_cb 300 self.rVal = apply(Pmw.EntryField, (rgbFrame,), entriesOption) 301 self.rVal.pack(side = 'left') 302 303 entriesOption['label_text'] = 'G' 304 entriesOption['value'] = "%4.2f"%self.currentRGB[1] 305 entriesOption['command'] = self.gVal_cb 306 self.gVal = apply(Pmw.EntryField, (rgbFrame,), entriesOption) 307 self.gVal.pack(side = 'left') 308 309 entriesOption['label_text'] = 'B' 310 entriesOption['value'] = "%4.2f"%self.currentRGB[2] 311 entriesOption['command'] = self.bVal_cb 312 self.bVal = apply(Pmw.EntryField, (rgbFrame,), entriesOption) 313 self.bVal.pack(side = 'left') 314 rgbFrame.pack(padx=4, pady=4,fill='both',expand=1) 315 316 hexFrame = Tkinter.Frame(entriesFrame) 317 entriesOption['label_text'] = 'Hex triplet' 318 entriesOption['value'] = self.currentHEX 319 entriesOption['command'] = self.hexVal_cb 320 del entriesOption['validate'] 321 entriesOption['entry_width']=8 322 #entriesOption['validate']='alphanumeric' 323 self.hexVal = apply(Pmw.EntryField, (hexFrame,), entriesOption) 324 self.hexVal.pack(padx=4, pady=4,side = 'left') 325 hexFrame.pack(fill='both',expand=1) 326 327 entriesFrame.pack(side = 'right', fill='both',expand=1) 328 bottomFrame.pack(side='bottom',fill='both', expand=1)
329 330 331 ############################################################### 332 #### COLOR CHOOSER UTILITY FUNCTIONs #### 333 ############################################################### 334 #def caluculate(self): 335
336 - def set(self, color, mode='RGB', trigger=1):
337 """Set the current color""" 338 #assert len(color)==3 339 assert mode in ['HSV', 'RGB', 'HEX'] 340 self.mode = mode 341 if mode == 'HSV': 342 newRGB = map(lambda x: float("%4.2f"%x), ToRGB(color)) 343 elif mode == 'HEX': 344 newRGB = ToRGB(color, mode = 'HEX') 345 else: newRGB = color 346 if newRGB != self.currentRGB: 347 self.updateWidgetsColor(newRGB) 348 if trigger==1 and self.immediate and self.cbManager.callbacks: 349 self.cbManager.CallCallbacks(self.currentRGB)
350
351 - def get(self, mode = 'RGB'):
352 assert mode in ['RGB','HSV', 'HEX'] 353 self.mode = mode 354 if mode == 'RGB': 355 return self.currentRGB 356 elif mode == 'HSV': 357 return self.currentHSV 358 elif mode == 'HEX': 359 col = ToHEX(self.currentRGB, mode='HEX') 360 return col
361
362 - def pack(self,*args, **kw):
363 apply(self.editFrame.pack, args, kw)
364
365 - def pack_forget(self,*args, **kw):
366 apply(self.editFrame.pack_forget, args, kw)
367
368 - def grid(self,*args, **kw):
369 apply(self.editFrame.grid, args, kw)
370
371 - def grid_forget(self,*args, **kw):
372 apply(self.editFrame.grid_forget, args, kw)
373 374 ############################################################### 375 #### WIDGETS CALLBACK FUNCTIONS #### 376 ############################################################### 377
378 - def colorWidget_cb(self, rgbcolor):
379 # Do this test because updateCurrent is called after the set 380 # cw. 381 # if color is different from current color then update chip 382 color=list(ToHSV(rgbcolor))[:] 383 color[2] = float(self.vScale.get()) 384 newrgb = list(ToRGB(color)) 385 if newrgb != self.currentRGB: 386 self.updateWidgetsColor(newrgb, who='cw')
387
388 - def scale_cb(self, val):
389 if self.afterID is not None: 390 self.vScale.after_cancel(self.afterID) 391 self.afterID = None 392 else: 393 self.afterID = self.vScale.after(17, self.scaleImm_cb, val)
394 395
396 - def scaleImm_cb(self, val):
397 newHSV = [float(self.hVal.get()),float(self.sVal.get()), float(val)] 398 if newHSV != self.currentHSV: 399 self.updateWidgetsColor(ToRGB(newHSV), who='scale')
400
401 - def scaleUp_cb(self, event=None):
402 val = float(self.vScale.get()) 403 newHSV = [float(self.hVal.get()),float(self.sVal.get()), float(val)] 404 if newHSV != self.currentHSV: 405 self.updateWidgetsColor(ToRGB(newHSV), who='scale')
406
407 - def hVal_cb(self):
408 val = float(self.hVal.get()) 409 newColor = self.currentHSV 410 newColor[0] = val 411 newHSV = map(lambda x: float("%4.2f"%x), newColor) 412 if (not (float(self.vVal.get())==0.00 or \ 413 (float(self.sVal.get())==0 and float(self.vVal.get())==1.0))): 414 self.updateWidgetsColor(ToRGB(newHSV), who='h')
415
416 - def sVal_cb(self):
417 val = float(self.sVal.get()) 418 newColor = list(ToHSV(self.currentRGB[:])) 419 newColor[1] = val 420 newHSV = map(lambda x: float("%4.2f"%x), newColor) 421 if (not float(self.vVal.get())==0) and newHSV != self.currentHSV: 422 self.updateWidgetsColor(ToRGB(newHSV), who='s')
423
424 - def vVal_cb(self):
425 newColor = [float(self.hVal.get()), 426 float(self.sVal.get()), 427 float(self.vVal.get())] 428 newHSV = map(lambda x: float("%4.2f"%x), newColor) 429 if newHSV != self.currentHSV: 430 self.updateWidgetsColor(ToRGB(newHSV), who='v')
431
432 - def rVal_cb(self):
433 val = float(self.rVal.get()) 434 newColor = self.currentRGB[:] 435 newColor[0] = val 436 newRGB = map(lambda x: float("%4.2f"%x), newColor) 437 if newRGB != self.currentRGB: 438 self.updateWidgetsColor(newRGB, who='r')
439 440
441 - def gVal_cb(self):
442 val = float(self.gVal.get()) 443 newColor = self.currentRGB[:] 444 newColor[1] = val 445 newRGB = map(lambda x: float("%4.2f"%x), newColor) 446 if newRGB != self.currentRGB: 447 self.updateWidgetsColor(newRGB, who='g')
448
449 - def bVal_cb(self):
450 val = float(self.bVal.get()) 451 newColor = self.currentRGB[:] 452 newColor[2] = val 453 newRGB = map(lambda x: float("%4.2f"%x), newColor) 454 if newRGB != self.currentRGB: 455 self.updateWidgetsColor(newRGB, who='b')
456 457
458 - def hexVal_cb(self):
459 val = self.hexVal.get() 460 if val[0] !='#' or len(val)!=7: 461 val = self.currentHEX 462 newRGB = ToRGB(val, 'HEX') 463 if newRGB != self.currentRGB: 464 self.updateWidgetsColor(newRGB, who='hex')
465 466 ############################################################### 467 #### WIDGETS UPDATE FUNCTIONS #### 468 ###############################################################
469 - def updateWidgetsColor(self, rgbcolor, who = 'set', trigger=1):
470 oldRGB = list(self.currentRGB) 471 self.currentRGB = map(lambda x: float("%4.2f"%x), rgbcolor) 472 # If newcolor is the same than old color nothing to update. 473 if oldRGB == self.currentRGB : return 474 hsvcolor = ToHSV(rgbcolor[:]) 475 self.currentHSV = map(lambda x: float("%4.2f"%x), hsvcolor) 476 self.currentHEX = ToHEX(self.currentRGB) 477 # Update the preview chip 478 self.chip.configure( bg = self.currentHEX ) 479 480 # ColorWidget: 481 cwColor = self.cw.get(mode='RGB') 482 newRGB = map(lambda x: float("%4.2f"%x),cwColor) 483 if newRGB != self.currentRGB and not who in ['v', 'scale']: 484 self.cw.set(self.currentRGB, mode='RGB',trigger=0) 485 486 # Value Scale: 487 scaleCol = self.vScale.get() 488 if scaleCol != self.currentHSV[2]: 489 self.vScale.set(self.currentHSV[2]) 490 491 # H Entry: 492 h = float(self.hVal.get()) 493 hCol = float("%4.2f"%h) 494 if hCol != self.currentHSV[0] and not who in ['v', 'scale']: 495 self.hVal.setentry(self.currentHSV[0]) 496 497 # S Entry: 498 s = float(self.sVal.get()) 499 sCol = float("%4.2f"%s) 500 if sCol != self.currentHSV[1] and self.currentHSV[2] !=0 \ 501 and not who in ['v', 'scale']: 502 self.sVal.setentry(self.currentHSV[1]) 503 504 # V Entry: 505 v = float(self.vVal.get()) 506 vCol = float("%4.2f"%v) 507 if vCol != self.currentHSV[2]and self.currentHSV[2] !=0: 508 self.vVal.setentry(self.currentHSV[2]) 509 510 # R Entry: 511 r = float(self.rVal.get()) 512 rCol = float("%4.2f"%r) 513 if rCol != self.currentRGB[0]: 514 self.rVal.setentry(self.currentRGB[0]) 515 # G Entry: 516 g = float(self.gVal.get()) 517 gCol=float("%4.2f"%g) 518 if gCol != self.currentRGB[1]: 519 self.gVal.setentry(self.currentRGB[1]) 520 521 # B Entry: 522 b = float(self.bVal.get()) 523 bCol = float("%4.2f"%b) 524 if bCol != self.currentRGB[2]: 525 self.bVal.setentry(self.currentRGB[2]) 526 527 # Hex Entry: 528 hexCol = self.hexVal.get() 529 if hexCol != self.currentHEX: 530 self.hexVal.setentry(self.currentHEX) 531 532 # This might depend of the mode. ? 533 if trigger==1 and self.immediate and self.cbManager.callbacks: 534 self.cbManager.CallCallbacks(self.currentRGB)
535 536 537
538 -class Chooser:
539 - def __init__(self, master=None, title = 'Chooser', commands = None, 540 immediate=0, exitFunction=None):
541 if master is None: 542 self.master = Tkinter.Toplevel() 543 self.ownmastert=1 544 #self.master.protocol('WM_DELETE_WINDOW', self.dismiss) 545 else: 546 self.ownmaster=0 547 self.master = master 548 # The editFrame is the main Frame of the widget 549 self.masterFrame = Tkinter.Frame(self.master, 550 borderwidth=2, relief='ridge') 551 self.immediate=immediate 552 # Create a cbManager 553 self.cbManager = CallbackManager() 554 self.createCommon() 555 self.createChooser() 556 if commands: 557 if type(commands) in [ListType, TupleType]: 558 map(self.cbManager.AddCallback, commands) 559 map(self.ce.cbManager.AddCallback, commands) 560 else: 561 self.cbManager.AddCallback(commands) 562 self.ce.cbManager.AddCallback(commands)
563 564
565 - def createCommon(self):
566 # Create the Menu Bar 567 self.menuBar = Pmw.MenuBar(self.masterFrame, 568 hull_relief = 'raised', 569 hull_borderwidth = 1) 570 self.menuBar.addmenu('File', 'Close this window or exit') 571 572 self.mainFrame = Tkinter.Frame(self.masterFrame, 573 borderwidth=2, relief='ridge', 574 width=150, height=200) 575 576 self.menuBar.pack(fill = 'x') 577 578 ## Create the ColorEditor 579 self.ce = ColorEditor(self.mainFrame, immediate=self.immediate) 580 581 self.hidden=1 582 self.mainFrame.pack(fill='both', expand=1)
583 584 ###################################################################### 585 #### UTILITY FUNCTIONS #### 586 ###################################################################### 587 588
589 - def createChooser(self):
590 pass
591
592 - def pack(self, *args, **kw):
593 apply(self.masterFrame.pack, args, kw)
594
595 - def pack_forget(self, *args, **kw):
596 apply(self.masterFrame.pack_forget, args, kw)
597
598 - def grid(self ,*args, **kw):
599 apply(self.masterFrame.grid, args, kw)
600
601 - def grid_forget(self, *args, **kw):
602 apply(self.masterFrame.grid_forget, args, kw)
603 604 605
606 -class ColorChooser(Chooser):
607 - def __init__(self, master=None, title = 'Chooser', commands = None, 608 immediate=0, exitFunction=None, colorsFile=None, 609 colorsName=None):
610 611 self.exitFunc = exitFunction 612 613 if colorsFile is None or colorsName is None: 614 path = __import__('mglutil').__path__ 615 self.customFilename = os.path.join(path[0],'gui/BasicWidgets/Tk/defaultColors.py') 616 self.colorsName = 'defaultColor' 617 618 else: 619 self.customFilename = colorsFile 620 self.colorsName = colorsName 621 622 Chooser.__init__(self, master=master, title=title, commands = commands, 623 immediate=immediate, exitFunction=exitFunction) 624 try: 625 self.master.protocol('WM_DELETE_WINDOW', self.exit) 626 except: 627 pass
628
629 - def createChooser(self):
630 self.ccFrame = Tkinter.Frame(self.mainFrame) 631 632 633 self.menuBar.addmenuitem('File', 'command', 'Load custom', 634 command = self.load, 635 label='Load') 636 637 self.menuBar.addmenuitem('File', 'command', 'Save Colors', 638 command = self.save, 639 label='Save') 640 641 self.menuBar.addmenuitem('File', 'separator') 642 643 self.menuBar.addmenuitem('File', 'command', 'Exit', 644 command=self.exit, 645 label='Exit') 646 647 self.menuBar.addmenu('Edit', 'editing commands') 648 649 self.menuBar.addmenuitem('Edit', 'command','Add New Color', 650 command = self.addColor, 651 label='Add New Color') 652 self.add = 0 653 654 self.menuBar.addmenuitem('Edit', 'command','Edit Custom Color', 655 command = self.editColor, 656 label='Edit Selected Color') 657 self.edit = 0 658 659 self.menuBar.addmenuitem('Edit', 'command','Hide Color Editor', 660 command = self.hideCE, 661 label='Hide Color Editor') 662 # Here we are creating the part of the widget that will contain the 663 # chips. 664 # ccFrame is the left part of the widget 665 self.ccFrame.pack(side='left',expand=1, fill='both') 666 self.addButton = Tkinter.Button(self.ccFrame, text='Add to custom', 667 command=self.addToCustom_cb) 668 self.addHidden = 1 669 670 # The chips frame will contain the color chips which are RadioSelect 671 # and it is a scrolledFrame. 672 chipsSFrame = Pmw.ScrolledFrame(self.ccFrame, usehullsize=1, 673 hull_width=130, 674 hull_height=200, 675 hscrollmode = 'none') 676 chipsSFrame.pack(padx = 5, pady = 3, fill = 'both', expand = 1) 677 678 # Create the RadioSelect empty 679 self.chipsFrame = chipsSFrame.interior() 680 681 self.colorChips=Pmw.RadioSelect(self.chipsFrame, 682 label_text='Default Colors', 683 labelpos='nw', orient='vertical', 684 buttontype='radiobutton', 685 command = self.colButton_cb) 686 self.mod = {} 687 execfile(self.customFilename, self.mod) 688 self.cFlag=0 689 self.addCustomCol(paletteName = self.colorsName)
690 691
692 - def load(self):
693 ftypes = [ ('Python files', '*.py') ] 694 filename = fileOpenAsk(self.master, types=ftypes, 695 title='Load custom colors' ) 696 # Open the module 697 if filename is None: return 698 self.customFilename = filename 699 self.mod = {} 700 execfile( self.customFilename, self.mod) 701 self.mod.keys() 702 colName = filter(lambda x: x[:2]!='__',self.mod.keys()) 703 entries = map(lambda x: (x, None), colName) 704 # From the module display the available colorPalette. 705 self.showChooser(entries)
706
707 - def showChooser(self, entries):
708 if self.cFlag == 1: 709 self.palChooser.clear() 710 map(self.palChooser.add, entries) 711 self.root.deiconify() 712 else: 713 self.root = Tkinter.Toplevel() 714 self.chooserFrame = Tkinter.Frame(self.root) 715 self.palChooser = ListChooser(self.chooserFrame, mode = 'extended', 716 title='Customized colors groups', 717 entries = entries, 718 command=self.addCustomCol,) 719 self.cFlag=1 720 dismissChooser = Tkinter.Button(self.chooserFrame, 721 text='Dismiss', 722 command=self.root.withdraw) 723 self.palChooser.pack() 724 dismissChooser.pack() 725 self.chooserFrame.pack()
726
727 - def hideCE(self):
728 if self.hidden == 0: 729 self.ce.pack_forget() 730 self.hidden=1 731 if self.addHidden == 0: 732 self.addButton.pack_forget() 733 self.addHidden=1 734 self.add =0 735 self.edit=0
736 737
738 - def addCustomCol(self, event=None, paletteName=None):
739 if paletteName is None: 740 paletteName = self.palChooser.get()[0] 741 self.colorsName = paletteName 742 # first clean up what is there: 743 if not self.mod.has_key(paletteName): 744 self.colDict={} 745 return 746 else: 747 self.colDict = self.mod[paletteName] 748 if len(self.colorChips._buttonList)!=0: 749 self.colorChips.deleteall() 750 751 self.colorChips.configure(label_text=paletteName) 752 items = self.colDict.items() 753 items.sort() 754 for name, value in items: 755 col = ToHEX(value) 756 self.colorChips.add(name, bg = col, 757 activebackground=col, 758 fg = col, activeforeground = col, 759 indicatoron=0,selectcolor=col, 760 width=10,height=1, 761 value = name) 762 self.colorChips.pack(fill='x', expand=1) 763 self.ce.cbManager.AddCallback(self.editChip) 764 765 if hasattr(self, 'chooserFrame'): 766 self.chooserFrame.master.withdraw()
767
768 - def save(self, fileName = None, paletteName=None):
769 """Save the color palette """ 770 if paletteName is None or fileName is None: 771 if hasattr(self, 'saveHidden'): 772 if self.saveHidden == 1: 773 self.root.deiconify() 774 self.saveHidden = 0 775 else: 776 self.root = Tkinter.Toplevel() 777 self.saveFrame = Tkinter.Frame(self.root, ) 778 groupFrame = Tkinter.Frame(self.saveFrame) 779 self.groupEntry = Pmw.EntryField(groupFrame, 780 label_text='Group name:', 781 labelpos='w', 782 value=self.colorsName) 783 label = Tkinter.Label(groupFrame, text="\t\t", 784 ) 785 self.groupEntry.pack(side='left') 786 label.pack(side='right', fill='x', expand=1) 787 groupFrame.pack(fill='x', expand=1) 788 789 fileFrame = Tkinter.Frame(self.saveFrame) 790 791 self.fileEntry = Pmw.EntryField(fileFrame, 792 label_text='Python File name:', 793 labelpos='w', 794 value=self.customFilename) 795 796 browseBut = Tkinter.Button(fileFrame, text='Browse', 797 command=self.browse) 798 self.fileEntry.pack(side='left') 799 browseBut.pack(side='right', fill='x', expand=1) 800 fileFrame.pack(fill='x', expand=1) 801 802 buttonFrame = Tkinter.Frame(self.saveFrame) 803 ok = Tkinter.Button(buttonFrame, text='OK', command=self.ok) 804 cancel = Tkinter.Button(buttonFrame, text='Cancel', 805 command=self.cancel) 806 ok.pack(side='left', fill='x',expand=1) 807 cancel.pack(side='right', fill='x', expand=1) 808 buttonFrame.pack(side='bottom', fill='both', expand=1) 809 self.saveFrame.pack(fill='both', expand=1) 810 811 self.saveHidden = 0
812
813 - def ok(self):
814 filename= self.fileEntry.get() 815 groupname = self.groupEntry.get() 816 if not groupname: 817 print 'ERROR' 818 if filename is None: return 819 if not os.path.isfile(filename): 820 f = open(filename, 'w') 821 s = groupname+'='+repr(self.colDict) 822 f.write(s) 823 f.write('\n') 824 f.close() 825 else: 826 mod = {} 827 execfile(filename, mod) 828 colName = filter(lambda x: x[:2]!='__',dir(mod.keys())) 829 if groupname in colName: 830 f = open(filename, 'w') 831 for name in colName: 832 if name == groupname: 833 s = groupname+'='+repr(self.colDict) 834 else: 835 dict = getattr(self.mod,name) 836 s = name+'='+repr(dict) 837 else: 838 f = open(filename, 'a+') 839 f.write('\n') 840 s = groupname+'='+repr(self.colDict) 841 f.write(s) 842 f.write('\n') 843 f.close() 844 self.root.withdraw()
845 846
847 - def cancel(self):
848 self.root.withdraw() 849 self.saveHidden=1
850
851 - def browse(self):
852 ftypes = [ ('Python files', '*.py') ] 853 854 filename = fileSaveAsk(self.master, types=ftypes, 855 title='Save custom colors') 856 if filename: 857 self.fileEntry.setentry(filename)
858
859 - def hide(self):
860 if hasattr(self.masterFrame.master,'withdraw'): 861 self.masterFrame.master.withdraw()
862
863 - def exit(self):
864 self.hideCE() 865 if self.exitFunc is None: 866 if hasattr(self.masterFrame.master,'withdraw'): 867 self.masterFrame.master.withdraw() 868 else: 869 self.exitFunc()
870
871 - def editColor(self):
872 if self.edit == 1: 873 return 874 self.edit = 1 875 if self.hidden == 1: 876 self.ce.pack(side = 'right', fill='both', expand=1) 877 self.hidden = 0 878 else: 879 if self.add == 0: 880 self.ce.pack_forget() 881 self.hidden=1 882 if self.addHidden == 0: 883 self.addButton.pack_forget() 884 self.addHidden=1 885 self.ce.immediate=1 886 self.add = 0
887
888 - def addColor(self):
889 if self.add ==1: return 890 if self.hidden: 891 self.ce.pack(side = 'right', fill='both', expand=1) 892 self.hidden=0 893 else: 894 if self.edit == 0: 895 self.ce.pack_forget() 896 self.hidden=1 897 if self.addHidden: 898 self.addButton.pack(side = 'bottom', fill='x', expand=1) 899 self.addHidden=0 900 self.ce.immediate=0 901 self.add = 1 902 self.edit = 0
903 904 905 ##################################################################### 906 ##### CALLBACKS 907 ####################################################################
908 - def editChip(self, col):
909 hexcol = ToHEX(col) 910 chipName = self.colorChips.getcurselection() 911 if chipName is None: return 912 chip = self.colorChips.button(chipName) 913 chip.configure(bg=hexcol, fg=hexcol, activebackground=hexcol, 914 activeforeground=hexcol, selectcolor=hexcol) 915 self.colDict[chipName]=col
916
917 - def colButton_cb(self, tag):
918 col = self.colDict[tag] 919 self.ce.set(col) 920 if self.edit == 0 or self.add==0: 921 self.cbManager.CallCallbacks(col)
922 923 924
925 - def addToCustom_cb(self):
926 rgbcol = self.ce.get() 927 newKey = str(len(self.colDict)+1) 928 self.colDict[newKey]=rgbcol 929 col = ToHEX(rgbcol) 930 self.colorChips.add(newKey, bg = col, 931 activebackground=col, 932 fg = col, activeforeground = col, 933 indicatoron=0,selectcolor=col, 934 width=10,height=1, value = newKey)
935
936 -class PaletteChooser(Chooser):
937 pass
938