~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to release/scripts/config.py

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: config.py,v 1.1 2005/04/16 05:25:41 ianwill Exp $
 
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, MAX_STR_LEN, MAX_ITEMS_NUM
 
110
 
 
111
# ---
 
112
# The "General" configure options key is managed from this script.
 
113
verbose = True
 
114
confirm_overwrite = True
 
115
 
 
116
tooltips = {
 
117
        'verbose': 'print script messages (info, warnings, errors) to the console',
 
118
        'confirm_overwrite': 'scripts should always confirm before overwriting files'
 
119
}
 
120
 
 
121
CFG_LIST = ['verbose', 'confirm_overwrite', 'tooltips']
 
122
KEY_NAME = 'General'
 
123
 
 
124
def update_registry():
 
125
        rd = {}
 
126
        for var in CFG_LIST:
 
127
                exec("rd['%s']=%s" % (var, var))
 
128
        Registry.SetKey(KEY_NAME, rd, True)
 
129
 
 
130
rd = Registry.GetKey('General', True)
 
131
if rd:
 
132
        try:
 
133
                for var in CFG_LIST[:-1]: # no need to update tooltips
 
134
                        exec("%s=rd['%s']" % (var, var))
 
135
        except: update_registry()
 
136
 
 
137
else:
 
138
        update_registry()
 
139
# ---
 
140
 
 
141
# script globals:
 
142
CFGKEY = ''
 
143
LABELS = []
 
144
GD = {} # groups dict (includes "Other" for unmapped keys)
 
145
INDEX = 0 # to pass button indices to fs callbacks
 
146
FREEKEY_IDX = 0 # index of set of keys not mapped to a script name
 
147
KEYMENUS = []
 
148
ALL_SCRIPTS = {}
 
149
ALL_GROUPS = []
 
150
START_SCREEN  = 0
 
151
CONFIG_SCREEN = 1
 
152
DISK_UPDATE = True # write changed data to its config file
 
153
 
 
154
ACCEPTED_TYPES = [bool, int, float, str, unicode]
 
155
 
 
156
SCREEN = START_SCREEN
 
157
 
 
158
SCROLL_DOWN = 0
 
159
 
 
160
# events:
 
161
BEVT_START = 50
 
162
BEVT_EXIT = 0 + BEVT_START
 
163
BEVT_BACK = 1 + BEVT_START
 
164
BEVT_DISK = 2 + BEVT_START
 
165
BEVT_CANCEL = 3 + BEVT_START
 
166
BEVT_APPLY = 4 + BEVT_START
 
167
BEVT_HELP = 5 + BEVT_START
 
168
BEVT_DEL = 6 + BEVT_START
 
169
BEVT_KEYMENU = []
 
170
BUT_KEYMENU = []
 
171
BEVT_BOOL = 100
 
172
BEVT_INT = BEVT_BOOL + MAX_ITEMS_NUM
 
173
BEVT_FLOAT = BEVT_BOOL + 2*MAX_ITEMS_NUM
 
174
BEVT_STR = BEVT_BOOL + 3*MAX_ITEMS_NUM
 
175
BEVT_BROWSEDIR = BEVT_BOOL + 4*MAX_ITEMS_NUM
 
176
BEVT_BROWSEFILE = BEVT_BOOL + 5*MAX_ITEMS_NUM
 
177
BUT_TYPES = {
 
178
        bool: 0,
 
179
        int: 0,
 
180
        float: 0,
 
181
        str: 0
 
182
}
 
183
 
 
184
# Function definitions:
 
185
 
 
186
def get_keys():
 
187
        LoadConfigData() # loads all data from files in (u)scripts/bpydata/config/
 
188
        return [k for k in Registry.Keys() if k[0] != "_"]
 
189
 
 
190
 
 
191
def show_help(script = 'config.py'):
 
192
        Blender.ShowHelp(script)
 
193
 
 
194
 
 
195
def fs_dir_callback(pathname):
 
196
        global CFGKEY, INDEX
 
197
 
 
198
        pathname = bsys.dirname(pathname)
 
199
        datatypes = CFGKEY.sorteddata
 
200
        datatypes[str][INDEX][1] = pathname
 
201
 
 
202
 
 
203
def fs_file_callback(pathname):
 
204
        global CFGKEY, INDEX
 
205
 
 
206
        datatypes = CFGKEY.sorteddata
 
207
        datatypes[str][INDEX][1] = pathname
 
208
 
 
209
 
 
210
# parse Bpymenus file to get all script filenames
 
211
# (used to show help for a given key)
 
212
def fill_scripts_dict():
 
213
        global ALL_SCRIPTS, ALL_GROUPS
 
214
 
 
215
        group = ''
 
216
        group_len = 0
 
217
        sep = bsys.sep
 
218
        home = Blender.Get('homedir')
 
219
        if not home:
 
220
                errmsg = """
 
221
Can't find Blender's home dir and so can't find the
 
222
Bpymenus file automatically stored inside it, which
 
223
is needed by this script.  Please run the
 
224
Help -> System -> System Information script to get
 
225
information about how to fix this.
 
226
"""
 
227
                raise SystemError, errmsg
 
228
        fname = bsys.join(home, 'Bpymenus')
 
229
        if not bsys.exists(fname): return False
 
230
        f = file(fname, 'r')
 
231
        lines = f.readlines()
 
232
        f.close()
 
233
        for l in lines:
 
234
                if l.rfind('{') > 0:
 
235
                        group = l.split()[0]
 
236
                        ALL_GROUPS.append(group)
 
237
                        group_len += 1
 
238
                        continue
 
239
                elif l[0] != "'": continue
 
240
                fields = l.split("'")
 
241
                if len(fields) > 2:
 
242
                        menuname = fields[1].replace('...','')
 
243
                        fields = fields[2].split()
 
244
                        if len(fields) > 1:
 
245
                                fname = fields[1].split(sep)[-1]
 
246
                                ALL_SCRIPTS[fname] = (menuname, group_len - 1)
 
247
        return True
 
248
 
 
249
 
 
250
def map_to_registered_script(name):
 
251
        global ALL_SCRIPTS
 
252
 
 
253
        if not name.endswith('.py'):
 
254
                name = "%s.py" % name
 
255
        if ALL_SCRIPTS.has_key(name):
 
256
                return ALL_SCRIPTS[name] # == (menuname, group index)
 
257
        return None
 
258
 
 
259
 
 
260
def reset():
 
261
        global LABELS, GD, KEYMENUS, KEYS
 
262
 
 
263
        # init_data is recalled when a key is deleted, so:
 
264
        LABELS = []
 
265
        GD = {}
 
266
        KEYMENUS = []
 
267
        KEYS = get_keys()
 
268
 
 
269
 
 
270
# gather all script info, fill gui menus
 
271
def init_data():
 
272
        global KEYS, GD, ALL_GROUPS, ALL_SCRIPTS, KEYMENUS, LABELS
 
273
        global BUT_KEYMENU, BEVT_KEYMENU, FREEKEY_IDX
 
274
 
 
275
        for k in ALL_GROUPS:
 
276
                GD[k] = []
 
277
        GD[None] = []
 
278
 
 
279
        for k in KEYS:
 
280
                res = map_to_registered_script(k)
 
281
                if res:
 
282
                        GD[ALL_GROUPS[res[1]]].append((k, res[0]))
 
283
                else: GD[None].append((k, k))
 
284
 
 
285
        for k in GD.keys():
 
286
                if not GD[k]: GD.pop(k)
 
287
 
 
288
        if GD.has_key(None):
 
289
                GD['Other'] = GD[None]
 
290
                GD.pop(None)
 
291
                FREEKEY_IDX = -1
 
292
 
 
293
        BUT_KEYMENU = range(len(GD))
 
294
 
 
295
        for k in GD.keys():
 
296
                kmenu = ['Configuration Keys: %s%%t' % k]
 
297
                for j in GD[k]:
 
298
                        kmenu.append(j[1])
 
299
                kmenu = "|".join(kmenu)
 
300
                KEYMENUS.append(kmenu)
 
301
                LABELS.append(k)
 
302
 
 
303
        if FREEKEY_IDX < 0:
 
304
                FREEKEY_IDX = LABELS.index('Other')
 
305
 
 
306
        length = len(KEYMENUS)
 
307
        BEVT_KEYMENU = range(1, length + 1)
 
308
        BUT_KEYMENU = range(length)
 
309
 
 
310
 
 
311
# for theme colors:
 
312
def float_colors(cols):
 
313
        return map(lambda x: x / 255.0, cols)
 
314
 
 
315
 
 
316
 
 
317
class Config:
 
318
 
 
319
        def __init__(self, key, has_group = True):
 
320
                global DISK_UPDATE
 
321
 
 
322
                self.key = key
 
323
                self.has_group = has_group
 
324
                self.name = key
 
325
                self.fromdisk = HasConfigData(key) & BPY_KEY_IN_FILE
 
326
                if not self.fromdisk: DISK_UPDATE = False
 
327
                else: DISK_UPDATE = True
 
328
 
 
329
                self.origdata = Registry.GetKey(key, True)
 
330
                data = self.data = self.origdata.copy()
 
331
 
 
332
                if not data:
 
333
                        Draw.PupMenu('ERROR: couldn\'t find requested data')
 
334
                        self.data = None
 
335
                        return
 
336
 
 
337
                keys = data.keys()
 
338
                nd = {}
 
339
                for k in keys:
 
340
                        nd[k.lower()] = k
 
341
 
 
342
                if nd.has_key('tooltips'):
 
343
                        ndval = nd['tooltips']
 
344
                        self.tips = data[ndval]
 
345
                        data.pop(ndval)
 
346
                else: self.tips = 0
 
347
 
 
348
                if nd.has_key('limits'):
 
349
                        ndval = nd['limits']
 
350
                        self.limits = data[ndval]
 
351
                        data.pop(ndval)
 
352
                else: self.limits = 0
 
353
 
 
354
                if self.has_group:
 
355
                        scriptname = key
 
356
                        if not scriptname.endswith('.py'):
 
357
                                scriptname = "%s.py" % scriptname
 
358
                elif nd.has_key('script'):
 
359
                                ndval = nd['script']
 
360
                                scriptname = data[ndval]
 
361
                                data.pop(ndval)
 
362
                                if not scriptname.endswith('.py'):
 
363
                                        scriptname = "%s.py" % scriptname
 
364
                else: scriptname = None
 
365
 
 
366
                self.scriptname = scriptname
 
367
 
 
368
                self.sort()
 
369
 
 
370
 
 
371
        def needs_update(self): # check if user changed data
 
372
                data = self.data
 
373
                new = self.sorteddata
 
374
 
 
375
                for vartype in new.keys():
 
376
                        for i in new[vartype]:
 
377
                                if data[i[0]] != i[1]: return 1
 
378
 
 
379
                return 0 # no changes
 
380
 
 
381
 
 
382
        def update(self): # update original key
 
383
                global DISK_UPDATE
 
384
 
 
385
                data = self.data
 
386
                odata = self.origdata
 
387
                new = self.sorteddata
 
388
                for vartype in new.keys():
 
389
                        for i in new[vartype]:
 
390
                                if data[i[0]] != i[1]: data[i[0]] = i[1]
 
391
                                if odata[i[0]] != i[1]: odata[i[0]] = i[1]
 
392
 
 
393
                if DISK_UPDATE: Registry.SetKey(self.key, odata, True)
 
394
 
 
395
        def delete(self):
 
396
                global DISK_UPDATE
 
397
 
 
398
                delmsg = 'OK?%t|Delete key from memory'
 
399
                if DISK_UPDATE:
 
400
                        delmsg = "%s and from disk" % delmsg
 
401
                if Draw.PupMenu(delmsg) == 1:
 
402
                        Registry.RemoveKey(self.key, DISK_UPDATE)
 
403
                        return True
 
404
 
 
405
                return False
 
406
 
 
407
 
 
408
        def revert(self): # revert to original key
 
409
                data = self.data
 
410
                new = self.sorteddata
 
411
                for vartype in new.keys():
 
412
                        for i in new[vartype]:
 
413
                                if data[i[0]] != i[1]: i[1] = data[i[0]]
 
414
 
 
415
 
 
416
        def sort(self): # create a new dict with types as keys
 
417
                global ACCEPTED_TYPES, BUT_TYPES
 
418
 
 
419
                data = self.data
 
420
                datatypes = {}
 
421
                keys = [k for k in data.keys() if k[0] != '_']
 
422
                for k in keys:
 
423
                        val = data[k]
 
424
                        tval = type(val)
 
425
                        if tval not in ACCEPTED_TYPES: continue
 
426
                        if not datatypes.has_key(tval):
 
427
                                datatypes[tval] = []
 
428
                        datatypes[type(val)].append([k, val])
 
429
                if datatypes.has_key(unicode):
 
430
                        if not datatypes.has_key(str): datatypes[str] = datatypes[unicode]
 
431
                        else:
 
432
                                for i in datatypes[unicode]: datatypes[str].append(i)
 
433
                        datatypes.pop(unicode)
 
434
                for k in datatypes.keys():
 
435
                        dk = datatypes[k]
 
436
                        dk.sort()
 
437
                        dk.reverse()
 
438
                        BUT_TYPES[k] = range(len(dk))
 
439
                self.sorteddata = datatypes
 
440
 
 
441
 
 
442
# GUI:
 
443
 
 
444
# gui callbacks:
 
445
 
 
446
def gui(): # drawing the screen
 
447
 
 
448
        global SCREEN, START_SCREEN, CONFIG_SCREEN, KEYMENUS, LABELS
 
449
        global BEVT_KEYMENU, BUT_KEYMENU, CFGKEY
 
450
        global BUT_TYPES, SCROLL_DOWN, VARS_NUM
 
451
 
 
452
        WIDTH, HEIGHT = Window.GetAreaSize()
 
453
 
 
454
        theme = Theme.Get()[0]
 
455
        tui = theme.get('ui')
 
456
        ttxt = theme.get('text')
 
457
 
 
458
        COL_BG = float_colors(ttxt.back)
 
459
        COL_TXT = ttxt.text
 
460
        COL_TXTHI = ttxt.text_hi
 
461
 
 
462
        BGL.glClearColor(COL_BG[0],COL_BG[1],COL_BG[2],COL_BG[3])
 
463
        BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
 
464
        BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
 
465
 
 
466
        if SCREEN == START_SCREEN:
 
467
                x = 10
 
468
                y = 10
 
469
                h = 20
 
470
                w = 90
 
471
                BGL.glRasterPos2i(x, y)
 
472
                Draw.Text('Select a configuration key to access it.  Press Q or ESC to leave.')
 
473
                km_len = len(KEYMENUS)
 
474
                km_columns = (WIDTH - x) / w
 
475
                if km_columns == 0: km_rows = km_len
 
476
                else:
 
477
                        km_rows = km_len / km_columns
 
478
                        if (km_len % km_columns): km_rows += 1
 
479
                if km_rows == 0: km_rows = 1
 
480
                ystart = y + 2*h*km_rows
 
481
                if ystart > (HEIGHT - 70): ystart = HEIGHT - 70
 
482
                y = ystart
 
483
                column = 1
 
484
                for i, km in enumerate(KEYMENUS):
 
485
                        column += 1
 
486
                        BGL.glRasterPos2i(x + 2, y + h + 5)
 
487
                        Draw.Text(LABELS[i])
 
488
                        BUT_KEYMENU[i] = Draw.Menu(km, BEVT_KEYMENU[i],
 
489
                                x, y, w - 10, h, 0, 'Choose a key to access its configuration data')
 
490
                        if column > km_columns:
 
491
                                column = 1
 
492
                                y -= 2*h
 
493
                                if y < 35: break
 
494
                                x = 10
 
495
                        else: x += w
 
496
                x = 10
 
497
                y = 50 + ystart
 
498
                BGL.glColor3ub(COL_TXTHI[0], COL_TXTHI[1], COL_TXTHI[2])
 
499
                BGL.glRasterPos2i(x, y)
 
500
                Draw.Text('Scripts Configuration Editor')
 
501
                Draw.PushButton('help', BEVT_HELP, x, 22, 45, 16,
 
502
                        'View help information about this script (hotkey: H)')
 
503
 
 
504
        elif SCREEN == CONFIG_SCREEN:
 
505
                x = y = 10
 
506
                h = 18
 
507
                data = CFGKEY.sorteddata
 
508
                tips = CFGKEY.tips
 
509
                fromdisk = CFGKEY.fromdisk
 
510
                limits = CFGKEY.limits
 
511
                VARS_NUM = 0
 
512
                for k in data.keys():
 
513
                        VARS_NUM += len(data[k])
 
514
                lines = VARS_NUM + 5 # to account for header and footer
 
515
                y = lines*h
 
516
                if y > HEIGHT - 20: y = HEIGHT - 20
 
517
                BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2])
 
518
                BGL.glRasterPos2i(x, y)
 
519
                Draw.Text('Scripts Configuration Editor')
 
520
                y -= 20
 
521
                BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
 
522
                txtsize = 10
 
523
                if HEIGHT < lines*h:
 
524
                        BGL.glRasterPos2i(10, 5)
 
525
                        txtsize += Draw.Text('Arrow keys or mouse wheel to scroll, ')
 
526
                BGL.glRasterPos2i(txtsize, 5)
 
527
                Draw.Text('Q or ESC to return.')
 
528
                BGL.glRasterPos2i(x, y)
 
529
                Draw.Text('Key: "%s"' % CFGKEY.name)
 
530
                bh = 16
 
531
                bw = 45
 
532
                by = 16
 
533
                i = -1
 
534
                if CFGKEY.scriptname:
 
535
                        i = 0
 
536
                        Draw.PushButton('help', BEVT_HELP, x, by, bw, bh,
 
537
                                'Show documentation for the script that owns this key (hotkey: H)')
 
538
                Draw.PushButton('back', BEVT_BACK, x + (1+i)*bw, by, bw, bh,
 
539
                        'Back to config keys selection screen (hotkey: ESC)')
 
540
                Draw.PushButton('exit', BEVT_EXIT, x + (2+i)*bw, by, bw, bh,
 
541
                        'Exit from Scripts Config Editor (hotkey: Q)')
 
542
                Draw.PushButton('revert', BEVT_CANCEL, x + (3+i)*bw, by, bw, bh,
 
543
                        'Revert data to original values (hotkey: U)')
 
544
                Draw.PushButton('apply', BEVT_APPLY, x + (4+i)*bw, by, bw, bh,
 
545
                        'Apply changes, if any (hotkey: ENTER)')
 
546
                delmsg = 'Delete this data key from memory'
 
547
                if fromdisk: delmsg = "%s and from disk" % delmsg
 
548
                Draw.PushButton('delete', BEVT_DEL, x + (5+i)*bw, by, bw, bh,
 
549
                        '%s (hotkey: DELETE)' % delmsg)
 
550
                if fromdisk:
 
551
                        Draw.Toggle("file", BEVT_DISK, x + 3 + (6+i)*bw, by, bw, bh, DISK_UPDATE,
 
552
                                'Update also the file where this config key is stored')
 
553
                i = -1
 
554
                top = -1
 
555
                y -= 20
 
556
                yend = 30
 
557
                if data.has_key(bool) and y > 0:
 
558
                        lst = data[bool]
 
559
                        for l in lst:
 
560
                                top += 1
 
561
                                i += 1
 
562
                                if top < SCROLL_DOWN: continue
 
563
                                y -= h
 
564
                                if y < yend: break
 
565
                                w = 20
 
566
                                tog = data[bool][i][1]
 
567
                                if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
 
568
                                else: tooltip = "click to toggle"
 
569
                                BUT_TYPES[bool][i] = Draw.Toggle("", BEVT_BOOL + i,
 
570
                                        x, y, w, h, tog, tooltip)
 
571
                                BGL.glRasterPos2i(x + w + 3, y + 5)
 
572
                                Draw.Text(l[0].lower().replace('_', ' '))
 
573
                        i = -1
 
574
                        y -= 5
 
575
                if data.has_key(int) and y > 0:
 
576
                        lst = data[int]
 
577
                        for l in lst:
 
578
                                w = 70
 
579
                                top += 1
 
580
                                i += 1
 
581
                                if top < SCROLL_DOWN: continue
 
582
                                y -= h
 
583
                                if y < yend: break
 
584
                                val = data[int][i][1]
 
585
                                if limits: min, max = limits[l[0]]
 
586
                                else: min, max = 0, 10
 
587
                                if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
 
588
                                else: tooltip = "click / drag to change"
 
589
                                BUT_TYPES[int][i] = Draw.Number("", BEVT_INT + i,
 
590
                                        x, y, w, h, val, min, max, tooltip)
 
591
                                BGL.glRasterPos2i(x + w + 3, y + 3)
 
592
                                Draw.Text(l[0].lower().replace('_', ' '))
 
593
                        i = -1
 
594
                        y -= 5
 
595
                if data.has_key(float) and y > 0:
 
596
                        lst = data[float]
 
597
                        for l in lst:
 
598
                                w = 70
 
599
                                top += 1
 
600
                                i += 1
 
601
                                if top < SCROLL_DOWN: continue
 
602
                                y -= h
 
603
                                if y < yend: break
 
604
                                val = data[float][i][1]
 
605
                                if limits: min, max = limits[l[0]]
 
606
                                else: min, max = 0.0, 1.0
 
607
                                if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
 
608
                                else: tooltip = "click and drag to change"
 
609
                                BUT_TYPES[float][i] = Draw.Number("", BEVT_FLOAT + i,
 
610
                                        x, y, w, h, val, min, max, tooltip)
 
611
                                BGL.glRasterPos2i(x + w + 3, y + 3)
 
612
                                Draw.Text(l[0].lower().replace('_', ' '))
 
613
                        i = -1
 
614
                        y -= 5
 
615
                if data.has_key(str) and y > 0:
 
616
                        lst = data[str]
 
617
                        for l in lst:
 
618
                                top += 1
 
619
                                i += 1
 
620
                                if top < SCROLL_DOWN: continue
 
621
                                y -= h
 
622
                                if y < yend: break
 
623
                                name = l[0].lower()
 
624
                                is_dir = is_file = False
 
625
                                if name.find('_dir', -4) > 0:   is_dir = True
 
626
                                elif name.find('_file', -5) > 0: is_file = True
 
627
                                w = WIDTH - 20
 
628
                                wbrowse = 50
 
629
                                if is_dir and w > wbrowse: w -= wbrowse
 
630
                                if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
 
631
                                else: tooltip = "click to write a new string"
 
632
                                name = name.replace('_',' ') + ': '
 
633
                                BUT_TYPES[str][i] = Draw.String(name, BEVT_STR + i,
 
634
                                        x, y, w, h, l[1], MAX_STR_LEN, tooltip)
 
635
                                if is_dir:
 
636
                                        Draw.PushButton('browse', BEVT_BROWSEDIR + i, x+w+1, y, wbrowse, h,
 
637
                                                'click to open a file selector (pick any file in the desired dir)')
 
638
                                elif is_file:
 
639
                                        Draw.PushButton('browse', BEVT_BROWSEFILE + i, x + w + 1, y, 50, h,
 
640
                                                'click to open a file selector')
 
641
 
 
642
 
 
643
def fit_scroll():
 
644
        global SCROLL_DOWN, VARS_NUM
 
645
        max = VARS_NUM - 1 # so last item is always visible
 
646
        if SCROLL_DOWN > max:
 
647
                SCROLL_DOWN = max
 
648
        elif SCROLL_DOWN < 0:
 
649
                SCROLL_DOWN = 0
 
650
 
 
651
 
 
652
def event(evt, val): # input events
 
653
 
 
654
        global SCREEN, START_SCREEN, CONFIG_SCREEN
 
655
        global SCROLL_DOWN, CFGKEY
 
656
 
 
657
        if not val: return
 
658
 
 
659
        if evt == Draw.ESCKEY:
 
660
                if SCREEN == START_SCREEN: Draw.Exit()
 
661
                else:
 
662
                        if CFGKEY.needs_update():
 
663
                                if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
 
664
                                        CFGKEY.update()
 
665
                        SCREEN = START_SCREEN
 
666
                        SCROLL_DOWN = 0
 
667
                        Draw.Redraw()
 
668
                return
 
669
        elif evt == Draw.QKEY:
 
670
                if SCREEN == CONFIG_SCREEN and CFGKEY.needs_update():
 
671
                        if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
 
672
                                CFGKEY.update()
 
673
                Draw.Exit()
 
674
                return
 
675
        elif evt == Draw.HKEY:
 
676
                if SCREEN == START_SCREEN: show_help()
 
677
                elif CFGKEY.scriptname: show_help(CFGKEY.scriptname)
 
678
                return
 
679
 
 
680
        elif SCREEN == CONFIG_SCREEN:
 
681
                if evt in [Draw.DOWNARROWKEY, Draw.WHEELDOWNMOUSE]:
 
682
                        SCROLL_DOWN += 1
 
683
                        fit_scroll()
 
684
                elif evt in [Draw.UPARROWKEY, Draw.WHEELUPMOUSE]:
 
685
                        SCROLL_DOWN -= 1
 
686
                        fit_scroll()
 
687
                elif evt == Draw.UKEY:
 
688
                        if CFGKEY.needs_update():
 
689
                                CFGKEY.revert()
 
690
                elif evt == Draw.RETKEY or evt == Draw.PADENTER:
 
691
                        if CFGKEY.needs_update():
 
692
                                CFGKEY.update()
 
693
                elif evt == Draw.DELKEY:
 
694
                        if CFGKEY.delete():
 
695
                                reset()
 
696
                                init_data()
 
697
                                SCREEN = START_SCREEN
 
698
                                SCROLL_DOWN = 0
 
699
                else: return
 
700
                Draw.Redraw()
 
701
 
 
702
 
 
703
def button_event(evt): # gui button events
 
704
 
 
705
        global SCREEN, START_SCREEN, CONFIG_SCREEN, CFGKEY, DISK_UPDATE
 
706
        global BEVT_KEYMENU, BUT_KEYMENU, BUT_TYPES, SCROLL_DOWN, GD, INDEX
 
707
        global BEVT_EXIT, BEVT_BACK, BEVT_APPLY, BEVT_CANCEL, BEVT_HELP, FREEKEY_IDX
 
708
 
 
709
        if SCREEN == START_SCREEN:
 
710
                for e in BEVT_KEYMENU:
 
711
                        if evt == e:
 
712
                                index = e - 1
 
713
                                k = BUT_KEYMENU[index].val - 1
 
714
                                CFGKEY = Config(GD[LABELS[index]][k][0], index != FREEKEY_IDX)
 
715
                                if CFGKEY.data:
 
716
                                        SCREEN = CONFIG_SCREEN
 
717
                                        Draw.Redraw()
 
718
                                        return
 
719
                if evt == BEVT_EXIT:
 
720
                        Draw.Exit()
 
721
                elif evt == BEVT_HELP:
 
722
                        show_help()
 
723
                return
 
724
 
 
725
        elif SCREEN == CONFIG_SCREEN:
 
726
                datatypes = CFGKEY.sorteddata
 
727
                if evt >= BEVT_BROWSEFILE:
 
728
                        INDEX = evt - BEVT_BROWSEFILE
 
729
                        Window.FileSelector(fs_file_callback, 'Choose file')
 
730
                elif evt >= BEVT_BROWSEDIR:
 
731
                        INDEX = evt - BEVT_BROWSEDIR
 
732
                        Window.FileSelector(fs_dir_callback, 'Choose any file')
 
733
                elif evt >= BEVT_STR:
 
734
                        var = BUT_TYPES[str][evt - BEVT_STR].val
 
735
                        datatypes[str][evt - BEVT_STR][1] = var
 
736
                elif evt >= BEVT_FLOAT:
 
737
                        var = BUT_TYPES[float][evt - BEVT_FLOAT].val
 
738
                        datatypes[float][evt - BEVT_FLOAT][1] = var
 
739
                elif evt >= BEVT_INT:
 
740
                        var = BUT_TYPES[int][evt - BEVT_INT].val
 
741
                        datatypes[int][evt - BEVT_INT][1] = var
 
742
                elif evt >= BEVT_BOOL:
 
743
                        var = datatypes[bool][evt - BEVT_BOOL][1]
 
744
                        if var == True: var = False
 
745
                        else: var = True
 
746
                        datatypes[bool][evt - BEVT_BOOL][1] = var
 
747
 
 
748
                elif evt == BEVT_BACK:
 
749
                        if SCREEN == CONFIG_SCREEN:
 
750
                                SCREEN = START_SCREEN
 
751
                                SCROLL_DOWN = 0
 
752
                                Draw.Redraw()
 
753
                elif evt == BEVT_EXIT:
 
754
                        if CFGKEY.needs_update():
 
755
                                if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
 
756
                                        CFGKEY.update()
 
757
                        Draw.Exit()
 
758
                        return
 
759
                elif evt == BEVT_APPLY:
 
760
                        if CFGKEY.needs_update():
 
761
                                CFGKEY.update()
 
762
                elif evt == BEVT_CANCEL:
 
763
                        if CFGKEY.needs_update():
 
764
                                CFGKEY.revert()
 
765
                elif evt == BEVT_DEL:
 
766
                        if CFGKEY.delete():
 
767
                                reset()
 
768
                                init_data()
 
769
                                SCREEN = START_SCREEN
 
770
                                SCROLL_DOWN = 0
 
771
                elif evt == BEVT_DISK:
 
772
                        if DISK_UPDATE: DISK_UPDATE = False
 
773
                        else: DISK_UPDATE = True
 
774
                elif evt == BEVT_HELP:
 
775
                        show_help(CFGKEY.scriptname)
 
776
                        return
 
777
                else:
 
778
                        return
 
779
        Draw.Redraw()
 
780
 
 
781
# End of definitions
 
782
 
 
783
 
 
784
KEYS = get_keys()
 
785
 
 
786
if not KEYS:
 
787
        Draw.PupMenu("NO DATA: please read this help screen")
 
788
        Blender.ShowHelp('config.py')
 
789
else:
 
790
        fill_scripts_dict()
 
791
        init_data()
 
792
        Draw.Register(gui, event, button_event)