python-2.5.2/win32/Tools/pynche/DetailsViewer.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 """DetailsViewer class.
       
     2 
       
     3 This class implements a pure input window which allows you to meticulously
       
     4 edit the current color.  You have both mouse control of the color (via the
       
     5 buttons along the bottom row), and there are keyboard bindings for each of the
       
     6 increment/decrement buttons.
       
     7 
       
     8 The top three check buttons allow you to specify which of the three color
       
     9 variations are tied together when incrementing and decrementing.  Red, green,
       
    10 and blue are self evident.  By tying together red and green, you can modify
       
    11 the yellow level of the color.  By tying together red and blue, you can modify
       
    12 the magenta level of the color.  By tying together green and blue, you can
       
    13 modify the cyan level, and by tying all three together, you can modify the
       
    14 grey level.
       
    15 
       
    16 The behavior at the boundaries (0 and 255) are defined by the `At boundary'
       
    17 option menu:
       
    18 
       
    19     Stop
       
    20         When the increment or decrement would send any of the tied variations
       
    21         out of bounds, the entire delta is discarded.
       
    22 
       
    23     Wrap Around
       
    24         When the increment or decrement would send any of the tied variations
       
    25         out of bounds, the out of bounds variation is wrapped around to the
       
    26         other side.  Thus if red were at 238 and 25 were added to it, red
       
    27         would have the value 7.
       
    28 
       
    29     Preseve Distance
       
    30         When the increment or decrement would send any of the tied variations
       
    31         out of bounds, all tied variations are wrapped as one, so as to
       
    32         preserve the distance between them.  Thus if green and blue were tied,
       
    33         and green was at 238 while blue was at 223, and an increment of 25
       
    34         were applied, green would be at 15 and blue would be at 0.
       
    35 
       
    36     Squash
       
    37         When the increment or decrement would send any of the tied variations
       
    38         out of bounds, the out of bounds variation is set to the ceiling of
       
    39         255 or floor of 0, as appropriate.  In this way, all tied variations
       
    40         are squashed to one edge or the other.
       
    41 
       
    42 The following key bindings can be used as accelerators.  Note that Pynche can
       
    43 fall behind if you hold the key down as a key repeat:
       
    44 
       
    45 Left arrow == -1
       
    46 Right arrow == +1
       
    47 
       
    48 Control + Left == -10
       
    49 Control + Right == 10
       
    50 
       
    51 Shift + Left == -25
       
    52 Shift + Right == +25
       
    53 """
       
    54 
       
    55 from Tkinter import *
       
    56 
       
    57 STOP = 'Stop'
       
    58 WRAP = 'Wrap Around'
       
    59 RATIO = 'Preserve Distance'
       
    60 GRAV = 'Squash'
       
    61 
       
    62 ADDTOVIEW = 'Details Window...'
       
    63 
       
    64 
       
    65 class DetailsViewer:
       
    66     def __init__(self, switchboard, master=None):
       
    67         self.__sb = switchboard
       
    68         optiondb = switchboard.optiondb()
       
    69         self.__red, self.__green, self.__blue = switchboard.current_rgb()
       
    70         # GUI
       
    71         root = self.__root = Toplevel(master, class_='Pynche')
       
    72         root.protocol('WM_DELETE_WINDOW', self.withdraw)
       
    73         root.title('Pynche Details Window')
       
    74         root.iconname('Pynche Details Window')
       
    75         root.bind('<Alt-q>', self.__quit)
       
    76         root.bind('<Alt-Q>', self.__quit)
       
    77         root.bind('<Alt-w>', self.withdraw)
       
    78         root.bind('<Alt-W>', self.withdraw)
       
    79         # accelerators
       
    80         root.bind('<KeyPress-Left>', self.__minus1)
       
    81         root.bind('<KeyPress-Right>', self.__plus1)
       
    82         root.bind('<Control-KeyPress-Left>', self.__minus10)
       
    83         root.bind('<Control-KeyPress-Right>', self.__plus10)
       
    84         root.bind('<Shift-KeyPress-Left>', self.__minus25)
       
    85         root.bind('<Shift-KeyPress-Right>', self.__plus25)
       
    86         #
       
    87         # color ties
       
    88         frame = self.__frame = Frame(root)
       
    89         frame.pack(expand=YES, fill=X)
       
    90         self.__l1 = Label(frame, text='Move Sliders:')
       
    91         self.__l1.grid(row=1, column=0, sticky=E)
       
    92         self.__rvar = IntVar()
       
    93         self.__rvar.set(optiondb.get('RSLIDER', 4))
       
    94         self.__radio1 = Checkbutton(frame, text='Red',
       
    95                                     variable=self.__rvar,
       
    96                                     command=self.__effect,
       
    97                                     onvalue=4, offvalue=0)
       
    98         self.__radio1.grid(row=1, column=1, sticky=W)
       
    99         self.__gvar = IntVar()
       
   100         self.__gvar.set(optiondb.get('GSLIDER', 2))
       
   101         self.__radio2 = Checkbutton(frame, text='Green',
       
   102                                     variable=self.__gvar,
       
   103                                     command=self.__effect,
       
   104                                     onvalue=2, offvalue=0)
       
   105         self.__radio2.grid(row=2, column=1, sticky=W)
       
   106         self.__bvar = IntVar()
       
   107         self.__bvar.set(optiondb.get('BSLIDER', 1))
       
   108         self.__radio3 = Checkbutton(frame, text='Blue',
       
   109                                     variable=self.__bvar,
       
   110                                     command=self.__effect,
       
   111                                     onvalue=1, offvalue=0)
       
   112         self.__radio3.grid(row=3, column=1, sticky=W)
       
   113         self.__l2 = Label(frame)
       
   114         self.__l2.grid(row=4, column=1, sticky=W)
       
   115         self.__effect()
       
   116         #
       
   117         # Boundary behavior
       
   118         self.__l3 = Label(frame, text='At boundary:')
       
   119         self.__l3.grid(row=5, column=0, sticky=E)
       
   120         self.__boundvar = StringVar()
       
   121         self.__boundvar.set(optiondb.get('ATBOUND', STOP))
       
   122         self.__omenu = OptionMenu(frame, self.__boundvar,
       
   123                                   STOP, WRAP, RATIO, GRAV)
       
   124         self.__omenu.grid(row=5, column=1, sticky=W)
       
   125         self.__omenu.configure(width=17)
       
   126         #
       
   127         # Buttons
       
   128         frame = self.__btnframe = Frame(frame)
       
   129         frame.grid(row=0, column=0, columnspan=2, sticky='EW')
       
   130         self.__down25 = Button(frame, text='-25',
       
   131                                command=self.__minus25)
       
   132         self.__down10 = Button(frame, text='-10',
       
   133                                command=self.__minus10)
       
   134         self.__down1 = Button(frame, text='-1',
       
   135                               command=self.__minus1)
       
   136         self.__up1 = Button(frame, text='+1',
       
   137                             command=self.__plus1)
       
   138         self.__up10 = Button(frame, text='+10',
       
   139                              command=self.__plus10)
       
   140         self.__up25 = Button(frame, text='+25',
       
   141                              command=self.__plus25)
       
   142         self.__down25.pack(expand=YES, fill=X, side=LEFT)
       
   143         self.__down10.pack(expand=YES, fill=X, side=LEFT)
       
   144         self.__down1.pack(expand=YES, fill=X, side=LEFT)
       
   145         self.__up1.pack(expand=YES, fill=X, side=LEFT)
       
   146         self.__up10.pack(expand=YES, fill=X, side=LEFT)
       
   147         self.__up25.pack(expand=YES, fill=X, side=LEFT)
       
   148 
       
   149     def __effect(self, event=None):
       
   150         tie = self.__rvar.get() + self.__gvar.get() + self.__bvar.get()
       
   151         if tie in (0, 1, 2, 4):
       
   152             text = ''
       
   153         else:
       
   154             text = '(= %s Level)' % {3: 'Cyan',
       
   155                                      5: 'Magenta',
       
   156                                      6: 'Yellow',
       
   157                                      7: 'Grey'}[tie]
       
   158         self.__l2.configure(text=text)
       
   159 
       
   160     def __quit(self, event=None):
       
   161         self.__root.quit()
       
   162 
       
   163     def withdraw(self, event=None):
       
   164         self.__root.withdraw()
       
   165 
       
   166     def deiconify(self, event=None):
       
   167         self.__root.deiconify()
       
   168 
       
   169     def __minus25(self, event=None):
       
   170         self.__delta(-25)
       
   171 
       
   172     def __minus10(self, event=None):
       
   173         self.__delta(-10)
       
   174 
       
   175     def __minus1(self, event=None):
       
   176         self.__delta(-1)
       
   177 
       
   178     def __plus1(self, event=None):
       
   179         self.__delta(1)
       
   180 
       
   181     def __plus10(self, event=None):
       
   182         self.__delta(10)
       
   183 
       
   184     def __plus25(self, event=None):
       
   185         self.__delta(25)
       
   186 
       
   187     def __delta(self, delta):
       
   188         tie = []
       
   189         if self.__rvar.get():
       
   190             red = self.__red + delta
       
   191             tie.append(red)
       
   192         else:
       
   193             red = self.__red
       
   194         if self.__gvar.get():
       
   195             green = self.__green + delta
       
   196             tie.append(green)
       
   197         else:
       
   198             green = self.__green
       
   199         if self.__bvar.get():
       
   200             blue = self.__blue + delta
       
   201             tie.append(blue)
       
   202         else:
       
   203             blue = self.__blue
       
   204         # now apply at boundary behavior
       
   205         atbound = self.__boundvar.get()
       
   206         if atbound == STOP:
       
   207             if red < 0 or green < 0 or blue < 0 or \
       
   208                red > 255 or green > 255 or blue > 255:
       
   209                 # then
       
   210                 red, green, blue = self.__red, self.__green, self.__blue
       
   211         elif atbound == WRAP or (atbound == RATIO and len(tie) < 2):
       
   212             if red < 0:
       
   213                 red += 256
       
   214             if green < 0:
       
   215                 green += 256
       
   216             if blue < 0:
       
   217                 blue += 256
       
   218             if red > 255:
       
   219                 red -= 256
       
   220             if green > 255:
       
   221                 green -= 256
       
   222             if blue > 255:
       
   223                 blue -= 256
       
   224         elif atbound == RATIO:
       
   225             # for when 2 or 3 colors are tied together
       
   226             dir = 0
       
   227             for c in tie:
       
   228                 if c < 0:
       
   229                     dir = -1
       
   230                 elif c > 255:
       
   231                     dir = 1
       
   232             if dir == -1:
       
   233                 delta = max(tie)
       
   234                 if self.__rvar.get():
       
   235                     red = red + 255 - delta
       
   236                 if self.__gvar.get():
       
   237                     green = green + 255 - delta
       
   238                 if self.__bvar.get():
       
   239                     blue = blue + 255 - delta
       
   240             elif dir == 1:
       
   241                 delta = min(tie)
       
   242                 if self.__rvar.get():
       
   243                     red = red - delta
       
   244                 if self.__gvar.get():
       
   245                     green = green - delta
       
   246                 if self.__bvar.get():
       
   247                     blue = blue - delta
       
   248         elif atbound == GRAV:
       
   249             if red < 0:
       
   250                 red = 0
       
   251             if green < 0:
       
   252                 green = 0
       
   253             if blue < 0:
       
   254                 blue = 0
       
   255             if red > 255:
       
   256                 red = 255
       
   257             if green > 255:
       
   258                 green = 255
       
   259             if blue > 255:
       
   260                 blue = 255
       
   261         self.__sb.update_views(red, green, blue)
       
   262         self.__root.update_idletasks()
       
   263 
       
   264     def update_yourself(self, red, green, blue):
       
   265         self.__red = red
       
   266         self.__green = green
       
   267         self.__blue = blue
       
   268 
       
   269     def save_options(self, optiondb):
       
   270         optiondb['RSLIDER'] = self.__rvar.get()
       
   271         optiondb['GSLIDER'] = self.__gvar.get()
       
   272         optiondb['BSLIDER'] = self.__bvar.get()
       
   273         optiondb['ATBOUND'] = self.__boundvar.get()