soc-2008-mxcurioni: merged changes to revision 14798, compilation works for rendering...
[blender-staging.git] / release / scripts / config.py
1 #!BPY
2
3 """
4 Name: 'Scripts Config Editor'
5 Blender: 236
6 Group: 'System'
7 Tooltip: 'View and edit available scripts configuration data'
8 """
9
10 __author__ = "Willian P. Germano"
11 __version__ = "0.1 2005/04/14"
12 __email__ = ('scripts', 'Author, wgermano:ig*com*br')
13 __url__ = ('blender', 'elysiun')
14
15 __bpydoc__ ="""\
16 This script can be used to view and edit configuration data stored
17 by other scripts.
18
19 Technical: this data is saved as dictionary keys with the
20 Blender.Registry module functions.  It is persistent while Blender is
21 running and, if the script's author chose to, is also saved to a file
22 in the scripts config data dir.
23
24 Usage:
25
26 - Start Screen:
27
28 To access any available key, select it from (one of) the menu(s).
29
30 Hotkeys:<br>
31    ESC or Q: [Q]uit<br>
32    H: [H]elp
33
34 - Keys Config Screen:
35
36 This screen exposes the configuration data for the chosen script key.  If the
37 buttons don't fit completely on the screen, you can scroll up or down with
38 arrow keys or a mouse wheel.  Leave the mouse pointer over any button to get
39 a tooltip about that option.
40
41 Any change can be reverted -- unless you have already applied it.
42
43 If the key is already stored in a config file, there will be a toggle button
44 (called 'file') that controls whether the changes will be written back to
45 the file or not.  If you just want to change the configuration for the current
46 session, simply unset that button.  Note, though, that data from files has
47 precedence over those keys already loaded in Blender, so if you re-run this
48 config editor, unsaved changes will not be seen.
49
50 Hotkeys:<br>
51    ESC: back to Start Screen<br>
52    Q: [Q]uit<br>
53    U: [U]ndo changes<br>
54    ENTER: apply changes (can't be reverted, then)<br>
55    UP, DOWN Arrows and mouse wheel: scroll text up / down
56
57 Notes:
58
59 a) Available keys are determined by which scripts you use.  If the key you
60 expect isn't available (or maybe there are none or too few keys), either the
61 related script doesn't need or still doesn't support this feature or the key
62 has not been stored yet, in which case you just need to run that script once
63 to make its config data available.
64
65 b) There are two places where config data files can be saved: the
66 bpydata/config/ dir (1) inside the default scripts dir or (2) inside the user
67 defined Python scripts dir
68 (User Preferences window -> File Paths tab -> Python path).  If available,
69 (2) is the default and also the recommended option, because then fresh Blender
70 installations won't delete your config data.  To use this option, simply set a
71 dir for Python scripts at the User Preferences window and make sure this dir
72 has the subdirs bpydata/ and bpydata/config/ inside it.
73
74 c) The key called "General" in the "Other" menu has general config options.
75 All scripts where that data is relevant are recommended to access it and set
76 behaviors accordingly.
77 """
78
79 # $Id$
80 #
81 # --------------------------------------------------------------------------
82 # config.py version 0.1 2005/04/08
83 # --------------------------------------------------------------------------
84 # ***** BEGIN GPL LICENSE BLOCK *****
85 #
86 # Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
87 #
88 # This program is free software; you can redistribute it and/or
89 # modify it under the terms of the GNU General Public License
90 # as published by the Free Software Foundation; either version 2
91 # of the License, or (at your option) any later version.
92 #
93 # This program is distributed in the hope that it will be useful,
94 # but WITHOUT ANY WARRANTY; without even the implied warranty of
95 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
96 # GNU General Public License for more details.
97 #
98 # You should have received a copy of the GNU General Public License
99 # along with this program; if not, write to the Free Software Foundation,
100 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
101 #
102 # ***** END GPL LICENCE BLOCK *****
103 # --------------------------------------------------------------------------
104
105 import Blender
106 from Blender import Draw, BGL, Registry, Window, sys as bsys
107 from Blender.Window import Theme
108 from BPyRegistry import LoadConfigData, SaveConfigData, HasConfigData,\
109         BPY_KEY_IN_FILE
110
111 MAX_STR_LEN = 300 # max length for a string
112 MAX_ITEMS_NUM = 100 # max number for each type of button
113
114 # ---
115 # The "General" configure options key is managed from this script.
116 verbose = True
117 confirm_overwrite = True
118
119 tooltips = {
120         'verbose': 'print script messages (info, warnings, errors) to the console',
121         'confirm_overwrite': 'scripts should always confirm before overwriting files'
122 }
123
124 CFG_LIST = ['verbose', 'confirm_overwrite', 'tooltips']
125 KEY_NAME = 'General'
126
127 def update_registry():
128         rd = {}
129         for var in CFG_LIST:
130                 exec("rd['%s']=%s" % (var, var))
131         Registry.SetKey(KEY_NAME, rd, True)
132
133 rd = Registry.GetKey('General', True)
134 if rd:
135         try:
136                 for var in CFG_LIST[:-1]: # no need to update tooltips
137                         exec("%s=rd['%s']" % (var, var))
138         except: update_registry()
139
140 else:
141         update_registry()
142 # ---
143
144 # script globals:
145 CFGKEY = ''
146 LABELS = []
147 GD = {} # groups dict (includes "Other" for unmapped keys)
148 INDEX = 0 # to pass button indices to fs callbacks
149 FREEKEY_IDX = 0 # index of set of keys not mapped to a script name
150 KEYMENUS = []
151 ALL_SCRIPTS = {}
152 ALL_GROUPS = []
153 START_SCREEN  = 0
154 CONFIG_SCREEN = 1
155 DISK_UPDATE = True # write changed data to its config file
156
157 ACCEPTED_TYPES = [bool, int, float, str, unicode]
158
159 SCREEN = START_SCREEN
160
161 SCROLL_DOWN = 0
162
163 # events:
164 BEVT_START = 50
165 BEVT_EXIT = 0 + BEVT_START
166 BEVT_BACK = 1 + BEVT_START
167 BEVT_DISK = 2 + BEVT_START
168 BEVT_CANCEL = 3 + BEVT_START
169 BEVT_APPLY = 4 + BEVT_START
170 BEVT_HELP = 5 + BEVT_START
171 BEVT_DEL = 6 + BEVT_START
172 BEVT_KEYMENU = []
173 BUT_KEYMENU = []
174 BEVT_BOOL = 100
175 BEVT_INT = BEVT_BOOL + MAX_ITEMS_NUM
176 BEVT_FLOAT = BEVT_BOOL + 2*MAX_ITEMS_NUM
177 BEVT_STR = BEVT_BOOL + 3*MAX_ITEMS_NUM
178 BEVT_BROWSEDIR = BEVT_BOOL + 4*MAX_ITEMS_NUM
179 BEVT_BROWSEFILE = BEVT_BOOL + 5*MAX_ITEMS_NUM
180 BUT_TYPES = {
181         bool: 0,
182         int: 0,
183         float: 0,
184         str: 0
185 }
186
187 # Function definitions:
188
189 def get_keys():
190         LoadConfigData() # loads all data from files in (u)scripts/bpydata/config/
191         return [k for k in Registry.Keys() if k[0] != "_"]
192
193
194 def show_help(script = 'config.py'):
195         Blender.ShowHelp(script)
196
197
198 def fs_dir_callback(pathname):
199         global CFGKEY, INDEX
200
201         pathname = bsys.dirname(pathname)
202         datatypes = CFGKEY.sorteddata
203         datatypes[str][INDEX][1] = pathname
204
205
206 def fs_file_callback(pathname):
207         global CFGKEY, INDEX
208
209         datatypes = CFGKEY.sorteddata
210         datatypes[str][INDEX][1] = pathname
211
212
213 # parse Bpymenus file to get all script filenames
214 # (used to show help for a given key)
215 def fill_scripts_dict():
216         global ALL_SCRIPTS, ALL_GROUPS
217
218         group = ''
219         group_len = 0
220         sep = bsys.sep
221         home = Blender.Get('homedir')
222         if not home:
223                 errmsg = """
224 Can't find Blender's home dir and so can't find the
225 Bpymenus file automatically stored inside it, which
226 is needed by this script.  Please run the
227 Help -> System -> System Information script to get
228 information about how to fix this.
229 """
230                 raise SystemError, errmsg
231         fname = bsys.join(home, 'Bpymenus')
232         if not bsys.exists(fname): return False
233         f = file(fname, 'r')
234         lines = f.readlines()
235         f.close()
236         for l in lines:
237                 if l.rfind('{') > 0:
238                         group = l.split()[0]
239                         ALL_GROUPS.append(group)
240                         group_len += 1
241                         continue
242                 elif l[0] != "'": continue
243                 fields = l.split("'")
244                 if len(fields) > 2:
245                         menuname = fields[1].replace('...','')
246                         fields = fields[2].split()
247                         if len(fields) > 1:
248                                 fname = fields[1].split(sep)[-1]
249                                 ALL_SCRIPTS[fname] = (menuname, group_len - 1)
250         return True
251
252
253 def map_to_registered_script(name):
254         global ALL_SCRIPTS
255
256         if not name.endswith('.py'):
257                 name = "%s.py" % name
258         if ALL_SCRIPTS.has_key(name):
259                 return ALL_SCRIPTS[name] # == (menuname, group index)
260         return None
261
262
263 def reset():
264         global LABELS, GD, KEYMENUS, KEYS
265
266         # init_data is recalled when a key is deleted, so:
267         LABELS = []
268         GD = {}
269         KEYMENUS = []
270         KEYS = get_keys()
271
272
273 # gather all script info, fill gui menus
274 def init_data():
275         global KEYS, GD, ALL_GROUPS, ALL_SCRIPTS, KEYMENUS, LABELS
276         global BUT_KEYMENU, BEVT_KEYMENU, FREEKEY_IDX
277
278         for k in ALL_GROUPS:
279                 GD[k] = []
280         GD[None] = []
281
282         for k in KEYS:
283                 res = map_to_registered_script(k)
284                 if res:
285                         GD[ALL_GROUPS[res[1]]].append((k, res[0]))
286                 else: GD[None].append((k, k))
287
288         for k in GD.keys():
289                 if not GD[k]: GD.pop(k)
290
291         if GD.has_key(None):
292                 GD['Other'] = GD[None]
293                 GD.pop(None)
294                 FREEKEY_IDX = -1
295
296         BUT_KEYMENU = range(len(GD))
297
298         for k in GD.keys():
299                 kmenu = ['Configuration Keys: %s%%t' % k]
300                 for j in GD[k]:
301                         kmenu.append(j[1])
302                 kmenu = "|".join(kmenu)
303                 KEYMENUS.append(kmenu)
304                 LABELS.append(k)
305
306         if FREEKEY_IDX < 0:
307                 FREEKEY_IDX = LABELS.index('Other')
308
309         length = len(KEYMENUS)
310         BEVT_KEYMENU = range(1, length + 1)
311         BUT_KEYMENU = range(length)
312
313
314 # for theme colors:
315 def float_colors(cols):
316         return map(lambda x: x / 255.0, cols)
317
318
319
320 class Config:
321
322         def __init__(self, key, has_group = True):
323                 global DISK_UPDATE
324
325                 self.key = key
326                 self.has_group = has_group
327                 self.name = key
328                 self.fromdisk = HasConfigData(key) & BPY_KEY_IN_FILE
329                 if not self.fromdisk: DISK_UPDATE = False
330                 else: DISK_UPDATE = True
331
332                 self.origdata = Registry.GetKey(key, True)
333                 data = self.data = self.origdata.copy()
334
335                 if not data:
336                         Draw.PupMenu('ERROR: couldn\'t find requested data')
337                         self.data = None
338                         return
339
340                 keys = data.keys()
341                 nd = {}
342                 for k in keys:
343                         nd[k.lower()] = k
344
345                 if nd.has_key('tooltips'):
346                         ndval = nd['tooltips']
347                         self.tips = data[ndval]
348                         data.pop(ndval)
349                 else: self.tips = 0
350
351                 if nd.has_key('limits'):
352                         ndval = nd['limits']
353                         self.limits = data[ndval]
354                         data.pop(ndval)
355                 else: self.limits = 0
356
357                 if self.has_group:
358                         scriptname = key
359                         if not scriptname.endswith('.py'):
360                                 scriptname = "%s.py" % scriptname
361                 elif nd.has_key('script'):
362                                 ndval = nd['script']
363                                 scriptname = data[ndval]
364                                 data.pop(ndval)
365                                 if not scriptname.endswith('.py'):
366                                         scriptname = "%s.py" % scriptname
367                 else: scriptname = None
368
369                 self.scriptname = scriptname
370
371                 self.sort()
372
373
374         def needs_update(self): # check if user changed data
375                 data = self.data
376                 new = self.sorteddata
377
378                 for vartype in new.keys():
379                         for i in new[vartype]:
380                                 if data[i[0]] != i[1]: return 1
381
382                 return 0 # no changes
383
384
385         def update(self): # update original key
386                 global DISK_UPDATE
387
388                 data = self.data
389                 odata = self.origdata
390                 new = self.sorteddata
391                 for vartype in new.keys():
392                         for i in new[vartype]:
393                                 if data[i[0]] != i[1]: data[i[0]] = i[1]
394                                 if odata[i[0]] != i[1]: odata[i[0]] = i[1]
395
396                 if DISK_UPDATE: Registry.SetKey(self.key, odata, True)
397
398         def delete(self):
399                 global DISK_UPDATE
400
401                 delmsg = 'OK?%t|Delete key from memory'
402                 if DISK_UPDATE:
403                         delmsg = "%s and from disk" % delmsg
404                 if Draw.PupMenu(delmsg) == 1:
405                         Registry.RemoveKey(self.key, DISK_UPDATE)
406                         return True
407
408                 return False
409
410
411         def revert(self): # revert to original key
412                 data = self.data
413                 new = self.sorteddata
414                 for vartype in new.keys():
415                         for i in new[vartype]:
416                                 if data[i[0]] != i[1]: i[1] = data[i[0]]
417
418
419         def sort(self): # create a new dict with types as keys
420                 global ACCEPTED_TYPES, BUT_TYPES
421
422                 data = self.data
423                 datatypes = {}
424                 keys = [k for k in data.keys() if k[0] != '_']
425                 for k in keys:
426                         val = data[k]
427                         tval = type(val)
428                         if tval not in ACCEPTED_TYPES: continue
429                         if not datatypes.has_key(tval):
430                                 datatypes[tval] = []
431                         datatypes[type(val)].append([k, val])
432                 if datatypes.has_key(unicode):
433                         if not datatypes.has_key(str): datatypes[str] = datatypes[unicode]
434                         else:
435                                 for i in datatypes[unicode]: datatypes[str].append(i)
436                         datatypes.pop(unicode)
437                 for k in datatypes.keys():
438                         dk = datatypes[k]
439                         dk.sort()
440                         dk.reverse()
441                         BUT_TYPES[k] = range(len(dk))
442                 self.sorteddata = datatypes
443
444
445 # GUI:
446
447 # gui callbacks:
448
449 def gui(): # drawing the screen
450
451         global SCREEN, START_SCREEN, CONFIG_SCREEN, KEYMENUS, LABELS
452         global BEVT_KEYMENU, BUT_KEYMENU, CFGKEY
453         global BUT_TYPES, SCROLL_DOWN, VARS_NUM
454
455         WIDTH, HEIGHT = Window.GetAreaSize()
456
457         theme = Theme.Get()[0]
458         tui = theme.get('ui')
459         ttxt = theme.get('text')
460
461         COL_BG = float_colors(ttxt.back)
462         COL_TXT = ttxt.text
463         COL_TXTHI = ttxt.text_hi
464
465         BGL.glClearColor(COL_BG[0],COL_BG[1],COL_BG[2],COL_BG[3])
466         BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
467         BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
468
469         if SCREEN == START_SCREEN:
470                 x = 10
471                 y = 10
472                 h = 20
473                 w = 90
474                 BGL.glRasterPos2i(x, y)
475                 Draw.Text('Select a configuration key to access it.  Press Q or ESC to leave.')
476                 km_len = len(KEYMENUS)
477                 km_columns = (WIDTH - x) / w
478                 if km_columns == 0: km_rows = km_len
479                 else:
480                         km_rows = km_len / km_columns
481                         if (km_len % km_columns): km_rows += 1
482                 if km_rows == 0: km_rows = 1
483                 ystart = y + 2*h*km_rows
484                 if ystart > (HEIGHT - 70): ystart = HEIGHT - 70
485                 y = ystart
486                 column = 1
487                 for i, km in enumerate(KEYMENUS):
488                         column += 1
489                         BGL.glRasterPos2i(x + 2, y + h + 5)
490                         Draw.Text(LABELS[i])
491                         BUT_KEYMENU[i] = Draw.Menu(km, BEVT_KEYMENU[i],
492                                 x, y, w - 10, h, 0, 'Choose a key to access its configuration data')
493                         if column > km_columns:
494                                 column = 1
495                                 y -= 2*h
496                                 if y < 35: break
497                                 x = 10
498                         else: x += w
499                 x = 10
500                 y = 50 + ystart
501                 BGL.glColor3ub(COL_TXTHI[0], COL_TXTHI[1], COL_TXTHI[2])
502                 BGL.glRasterPos2i(x, y)
503                 Draw.Text('Scripts Configuration Editor')
504                 Draw.PushButton('help', BEVT_HELP, x, 22, 45, 16,
505                         'View help information about this script (hotkey: H)')
506
507         elif SCREEN == CONFIG_SCREEN:
508                 x = y = 10
509                 h = 18
510                 data = CFGKEY.sorteddata
511                 tips = CFGKEY.tips
512                 fromdisk = CFGKEY.fromdisk
513                 limits = CFGKEY.limits
514                 VARS_NUM = 0
515                 for k in data.keys():
516                         VARS_NUM += len(data[k])
517                 lines = VARS_NUM + 5 # to account for header and footer
518                 y = lines*h
519                 if y > HEIGHT - 20: y = HEIGHT - 20
520                 BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2])
521                 BGL.glRasterPos2i(x, y)
522                 Draw.Text('Scripts Configuration Editor')
523                 y -= 20
524                 BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
525                 txtsize = 10
526                 if HEIGHT < lines*h:
527                         BGL.glRasterPos2i(10, 5)
528                         txtsize += Draw.Text('Arrow keys or mouse wheel to scroll, ')
529                 BGL.glRasterPos2i(txtsize, 5)
530                 Draw.Text('Q or ESC to return.')
531                 BGL.glRasterPos2i(x, y)
532                 Draw.Text('Key: "%s"' % CFGKEY.name)
533                 bh = 16
534                 bw = 45
535                 by = 16
536                 i = -1
537                 if CFGKEY.scriptname:
538                         i = 0
539                         Draw.PushButton('help', BEVT_HELP, x, by, bw, bh,
540                                 'Show documentation for the script that owns this key (hotkey: H)')
541                 Draw.PushButton('back', BEVT_BACK, x + (1+i)*bw, by, bw, bh,
542                         'Back to config keys selection screen (hotkey: ESC)')
543                 Draw.PushButton('exit', BEVT_EXIT, x + (2+i)*bw, by, bw, bh,
544                         'Exit from Scripts Config Editor (hotkey: Q)')
545                 Draw.PushButton('revert', BEVT_CANCEL, x + (3+i)*bw, by, bw, bh,
546                         'Revert data to original values (hotkey: U)')
547                 Draw.PushButton('apply', BEVT_APPLY, x + (4+i)*bw, by, bw, bh,
548                         'Apply changes, if any (hotkey: ENTER)')
549                 delmsg = 'Delete this data key from memory'
550                 if fromdisk: delmsg = "%s and from disk" % delmsg
551                 Draw.PushButton('delete', BEVT_DEL, x + (5+i)*bw, by, bw, bh,
552                         '%s (hotkey: DELETE)' % delmsg)
553                 if fromdisk:
554                         Draw.Toggle("file", BEVT_DISK, x + 3 + (6+i)*bw, by, bw, bh, DISK_UPDATE,
555                                 'Update also the file where this config key is stored')
556                 i = -1
557                 top = -1
558                 y -= 20
559                 yend = 30
560                 if data.has_key(bool) and y > 0:
561                         lst = data[bool]
562                         for l in lst:
563                                 top += 1
564                                 i += 1
565                                 if top < SCROLL_DOWN: continue
566                                 y -= h
567                                 if y < yend: break
568                                 w = 20
569                                 tog = data[bool][i][1]
570                                 if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
571                                 else: tooltip = "click to toggle"
572                                 BUT_TYPES[bool][i] = Draw.Toggle("", BEVT_BOOL + i,
573                                         x, y, w, h, tog, tooltip)
574                                 BGL.glRasterPos2i(x + w + 3, y + 5)
575                                 Draw.Text(l[0].lower().replace('_', ' '))
576                         i = -1
577                         y -= 5
578                 if data.has_key(int) and y > 0:
579                         lst = data[int]
580                         for l in lst:
581                                 w = 70
582                                 top += 1
583                                 i += 1
584                                 if top < SCROLL_DOWN: continue
585                                 y -= h
586                                 if y < yend: break
587                                 val = data[int][i][1]
588                                 if limits: min, max = limits[l[0]]
589                                 else: min, max = 0, 10
590                                 if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
591                                 else: tooltip = "click / drag to change"
592                                 BUT_TYPES[int][i] = Draw.Number("", BEVT_INT + i,
593                                         x, y, w, h, val, min, max, tooltip)
594                                 BGL.glRasterPos2i(x + w + 3, y + 3)
595                                 Draw.Text(l[0].lower().replace('_', ' '))
596                         i = -1
597                         y -= 5
598                 if data.has_key(float) and y > 0:
599                         lst = data[float]
600                         for l in lst:
601                                 w = 70
602                                 top += 1
603                                 i += 1
604                                 if top < SCROLL_DOWN: continue
605                                 y -= h
606                                 if y < yend: break
607                                 val = data[float][i][1]
608                                 if limits: min, max = limits[l[0]]
609                                 else: min, max = 0.0, 1.0
610                                 if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
611                                 else: tooltip = "click and drag to change"
612                                 BUT_TYPES[float][i] = Draw.Number("", BEVT_FLOAT + i,
613                                         x, y, w, h, val, min, max, tooltip)
614                                 BGL.glRasterPos2i(x + w + 3, y + 3)
615                                 Draw.Text(l[0].lower().replace('_', ' '))
616                         i = -1
617                         y -= 5
618                 if data.has_key(str) and y > 0:
619                         lst = data[str]
620                         for l in lst:
621                                 top += 1
622                                 i += 1
623                                 if top < SCROLL_DOWN: continue
624                                 y -= h
625                                 if y < yend: break
626                                 name = l[0].lower()
627                                 is_dir = is_file = False
628                                 if name.find('_dir', -4) > 0:   is_dir = True
629                                 elif name.find('_file', -5) > 0: is_file = True
630                                 w = WIDTH - 20
631                                 wbrowse = 50
632                                 if is_dir and w > wbrowse: w -= wbrowse
633                                 if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
634                                 else: tooltip = "click to write a new string"
635                                 name = name.replace('_',' ') + ': '
636                                 if len(l[1]) > MAX_STR_LEN:
637                                         l[1] = l[1][:MAX_STR_LEN]
638                                 BUT_TYPES[str][i] = Draw.String(name, BEVT_STR + i,
639                                         x, y, w, h, l[1], MAX_STR_LEN, tooltip)
640                                 if is_dir:
641                                         Draw.PushButton('browse', BEVT_BROWSEDIR + i, x+w+1, y, wbrowse, h,
642                                                 'click to open a file selector (pick any file in the desired dir)')
643                                 elif is_file:
644                                         Draw.PushButton('browse', BEVT_BROWSEFILE + i, x + w + 1, y, 50, h,
645                                                 'click to open a file selector')
646
647
648 def fit_scroll():
649         global SCROLL_DOWN, VARS_NUM
650         max = VARS_NUM - 1 # so last item is always visible
651         if SCROLL_DOWN > max:
652                 SCROLL_DOWN = max
653         elif SCROLL_DOWN < 0:
654                 SCROLL_DOWN = 0
655
656
657 def event(evt, val): # input events
658
659         global SCREEN, START_SCREEN, CONFIG_SCREEN
660         global SCROLL_DOWN, CFGKEY
661
662         if not val: return
663
664         if evt == Draw.ESCKEY:
665                 if SCREEN == START_SCREEN: Draw.Exit()
666                 else:
667                         if CFGKEY.needs_update():
668                                 if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
669                                         CFGKEY.update()
670                         SCREEN = START_SCREEN
671                         SCROLL_DOWN = 0
672                         Draw.Redraw()
673                 return
674         elif evt == Draw.QKEY:
675                 if SCREEN == CONFIG_SCREEN and CFGKEY.needs_update():
676                         if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
677                                 CFGKEY.update()
678                 Draw.Exit()
679                 return
680         elif evt == Draw.HKEY:
681                 if SCREEN == START_SCREEN: show_help()
682                 elif CFGKEY.scriptname: show_help(CFGKEY.scriptname)
683                 return
684
685         elif SCREEN == CONFIG_SCREEN:
686                 if evt in [Draw.DOWNARROWKEY, Draw.WHEELDOWNMOUSE]:
687                         SCROLL_DOWN += 1
688                         fit_scroll()
689                 elif evt in [Draw.UPARROWKEY, Draw.WHEELUPMOUSE]:
690                         SCROLL_DOWN -= 1
691                         fit_scroll()
692                 elif evt == Draw.UKEY:
693                         if CFGKEY.needs_update():
694                                 CFGKEY.revert()
695                 elif evt == Draw.RETKEY or evt == Draw.PADENTER:
696                         if CFGKEY.needs_update():
697                                 CFGKEY.update()
698                 elif evt == Draw.DELKEY:
699                         if CFGKEY.delete():
700                                 reset()
701                                 init_data()
702                                 SCREEN = START_SCREEN
703                                 SCROLL_DOWN = 0
704                 else: return
705                 Draw.Redraw()
706
707
708 def button_event(evt): # gui button events
709
710         global SCREEN, START_SCREEN, CONFIG_SCREEN, CFGKEY, DISK_UPDATE
711         global BEVT_KEYMENU, BUT_KEYMENU, BUT_TYPES, SCROLL_DOWN, GD, INDEX
712         global BEVT_EXIT, BEVT_BACK, BEVT_APPLY, BEVT_CANCEL, BEVT_HELP, FREEKEY_IDX
713
714         if SCREEN == START_SCREEN:
715                 for e in BEVT_KEYMENU:
716                         if evt == e:
717                                 index = e - 1
718                                 k = BUT_KEYMENU[index].val - 1
719                                 CFGKEY = Config(GD[LABELS[index]][k][0], index != FREEKEY_IDX)
720                                 if CFGKEY.data:
721                                         SCREEN = CONFIG_SCREEN
722                                         Draw.Redraw()
723                                         return
724                 if evt == BEVT_EXIT:
725                         Draw.Exit()
726                 elif evt == BEVT_HELP:
727                         show_help()
728                 return
729
730         elif SCREEN == CONFIG_SCREEN:
731                 datatypes = CFGKEY.sorteddata
732                 if evt >= BEVT_BROWSEFILE:
733                         INDEX = evt - BEVT_BROWSEFILE
734                         Window.FileSelector(fs_file_callback, 'Choose file')
735                 elif evt >= BEVT_BROWSEDIR:
736                         INDEX = evt - BEVT_BROWSEDIR
737                         Window.FileSelector(fs_dir_callback, 'Choose any file')
738                 elif evt >= BEVT_STR:
739                         var = BUT_TYPES[str][evt - BEVT_STR].val
740                         datatypes[str][evt - BEVT_STR][1] = var
741                 elif evt >= BEVT_FLOAT:
742                         var = BUT_TYPES[float][evt - BEVT_FLOAT].val
743                         datatypes[float][evt - BEVT_FLOAT][1] = var
744                 elif evt >= BEVT_INT:
745                         var = BUT_TYPES[int][evt - BEVT_INT].val
746                         datatypes[int][evt - BEVT_INT][1] = var
747                 elif evt >= BEVT_BOOL:
748                         var = datatypes[bool][evt - BEVT_BOOL][1]
749                         if var == True: var = False
750                         else: var = True
751                         datatypes[bool][evt - BEVT_BOOL][1] = var
752
753                 elif evt == BEVT_BACK:
754                         if SCREEN == CONFIG_SCREEN:
755                                 SCREEN = START_SCREEN
756                                 SCROLL_DOWN = 0
757                                 Draw.Redraw()
758                 elif evt == BEVT_EXIT:
759                         if CFGKEY.needs_update():
760                                 if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
761                                         CFGKEY.update()
762                         Draw.Exit()
763                         return
764                 elif evt == BEVT_APPLY:
765                         if CFGKEY.needs_update():
766                                 CFGKEY.update()
767                 elif evt == BEVT_CANCEL:
768                         if CFGKEY.needs_update():
769                                 CFGKEY.revert()
770                 elif evt == BEVT_DEL:
771                         if CFGKEY.delete():
772                                 reset()
773                                 init_data()
774                                 SCREEN = START_SCREEN
775                                 SCROLL_DOWN = 0
776                 elif evt == BEVT_DISK:
777                         if DISK_UPDATE: DISK_UPDATE = False
778                         else: DISK_UPDATE = True
779                 elif evt == BEVT_HELP:
780                         show_help(CFGKEY.scriptname)
781                         return
782                 else:
783                         return
784         Draw.Redraw()
785
786 # End of definitions
787
788
789 KEYS = get_keys()
790
791 if not KEYS:
792         Draw.PupMenu("NO DATA: please read this help screen")
793         Blender.ShowHelp('config.py')
794 else:
795         fill_scripts_dict()
796         init_data()
797         Draw.Register(gui, event, button_event)