4
Name: 'BPy Doc Browser'
7
Tip: 'Browse BPython (scripting API) modules doc strings.'
10
__author__ = "Daniel Dunbar"
11
__url__ = ("blender", "elysiun")
14
The "Doc Browser" lets users navigate the documentation strings of part of
15
the Blender Python API.
17
It doesn't give access yet to object method functions and variables, only to
18
module functions, but still it is a handy reference.
21
Page Up / Page Down: scroll 5 lines at a time;<br>
22
Up / Down arrow keys or mouse wheel: scroll one line at a time.
25
Everyone interested in the bpython api is also invited to read "The Blender
26
Python API Reference" doc, available online ("Python Scripting Reference"
27
entry in Blender's Help menu).
31
# $Id: doc_browser.py,v 1.5 2006/12/12 05:29:42 campbellbarton Exp $
33
# --------------------------------------------------------------------------
34
# ***** BEGIN GPL LICENSE BLOCK *****
36
# Copyright (C) 2004: Daniel Dunbar, ddunbar _at_ diads.com
38
# This program is free software; you can redistribute it and/or
39
# modify it under the terms of the GNU General Public License
40
# as published by the Free Software Foundation; either version 2
41
# of the License, or (at your option) any later version.
43
# This program is distributed in the hope that it will be useful,
44
# but WITHOUT ANY WARRANTY; without even the implied warranty of
45
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46
# GNU General Public License for more details.
48
# You should have received a copy of the GNU General Public License
49
# along with this program; if not, write to the Free Software Foundation,
50
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
52
# ***** END GPL LICENCE BLOCK *****
53
# --------------------------------------------------------------------------
56
# Blender help browser
59
# This should function as a self-explanatory (interface, not code)
60
# (mostly) help browser. The code is wacky and nasty and or fun,
61
# but mainly bad, just cause it works doesn't mean its readable!
65
# The row_draw function could easily be made into a more generic
66
# and usefull table drawing function...
70
from types import ListType, IntType, FloatType, StringType, ModuleType
71
from Blender.Draw import *
72
from Blender.BGL import *
74
# Simple version check, since I use the
75
# buffer calls... DONT use this code,
76
# assume everyone has 1.73+, and force
77
# them to upgrade if they dont
84
# I could have used the split from the string module,
85
# but some people might not have it
89
if s in on: out.append("")
90
else: out[-1]= out[-1]+s
92
if out[-1]=="": del(out[-1])
96
last_sort= 1; direction= 1
97
def sort_browselist(type):
99
global last_sort, direction
101
if (type==last_sort): direction= -direction
107
def byname(x, y): return cmp(x[0],y[0]);
108
def bytype(x, y): return cmp(x[1],y[1])
109
def bydata(x, y): return cmp(x[2],y[2])
111
def byname(x, y): return cmp(y[0],x[0]);
112
def bytype(x, y): return cmp(y[1],x[1])
113
def bydata(x, y): return cmp(y[2],x[2])
115
if (type==1): browselist.sort(byname)
116
elif (type==2): browselist.sort(bytype)
117
elif (type==3): browselist.sort(bydata)
121
global selected, selected_page
123
if (selected==num): selected= -1
129
def toggle_function_filter():
130
global function_filter
132
function_filter= not function_filter
138
selected_page= selected_page + dir
140
browse_scrollstart= 0
141
def browse_module(num):
142
global browsing, selected, browse_scrollstart
144
# cant go back from Blender
145
if browsing.val == 'Blender' and num == -1:
148
if (num>=0): newstr= browsing.val + "." + browselist[num][0]
150
modules= split(browsing.val, ".")
152
for m in modules[:-1]:
155
browsing= Create(newstr)
158
browsing= Create('Blender')
161
browse_scrollstart= 0
165
def make_browselist():
169
module= eval(browsing.val)
171
Blender.Draw.PupMenu('Error%t|Module is invalid')
172
browsing.val = 'Blender'
180
for item_name in items:
181
if (item_name[:2]=='__'): continue
183
data= [item_name, 'None', '', '']
184
item= eval(item_name,module.__dict__)
187
if (t==IntType): data[1]= 'Int'; data[2]= `item`
188
elif (t==FloatType): data[1]= 'Float'; data[2]= `item`
189
elif (t==StringType): data[1]= 'String'
190
elif (t==ModuleType): data[1]= 'Module'
191
elif (callable(item)):
194
if (doc): data[3]= doc
196
if (function_filter and data[1]!='Function'): continue
198
browselist.append(data)
200
browsing= Create('Blender')
222
browse_scrollstart= 0
224
winrect= [0.0, 0.0, 0.0, 0.0]
226
global browsing, winrect, scr, browse_scrollstart
228
# Blender doesn't give us direct access to
229
# the window size yet, but it does set the
230
# GL scissor box for it, so we can get the
234
size= Buffer(GL_FLOAT, None, 4)
235
glGetFloat(GL_SCISSOR_BOX, size)
238
size= Buffer(GL_FLOAT, 4)
239
glGetFloatv(GL_SCISSOR_BOX, size)
244
size[0]= size[1]= 0.0
246
# Shrink the size to make a nice frame
247
# (also a good technique so you can be sure you are clipping things properly)
248
size[0], size[1]= int(size[0]+10), int(size[1]+10)
249
size[2], size[3]= int(size[2]-12), int(size[3]-10)
251
glClearColor(0.6, 0.5, 0.3, 0.0)
252
glClear(GL_COLOR_BUFFER_BIT)
255
glColor3f(0.4, 0.5, 0.2)
256
glRectf(size[0], size[1], size[2], size[3])
259
glColor3f(0.2, 0.2, 0.4)
260
glRectf(size[0], size[3]-25, size[2], size[3])
262
glColor3f(0.6, 0.6, 0.6)
263
glRasterPos2f(size[0]+15, size[3]-17)
264
Text("Zr's Help Browser")
266
Button("Filter", FILTER_DISPLAY, size[2]-400, size[3]-22, 45, 18)
267
Button("Back", BACK_MODULE, size[2]-300, size[3]-22, 45, 18)
268
browsing= String("Browse: ", BROWSE_EVT, size[2]-250, size[3]-22, 245, 18, browsing.val, 30)
271
def row_draw(rect, data, cols, cell_colors, text_colors):
272
if (len(data)!=len(cols)):
273
print "Must have same length data and columns"
276
if (type(cell_colors)!=ListType): cell_colors= [cell_colors]
277
if (type(text_colors)!=ListType): text_colors= [text_colors]
280
for i in range(len(data)):
286
if (type(c)==FloatType): c= c*(rect[2]-rect[0])
289
color= cell_colors[i%len(cell_colors)]
290
apply(glColor3f, color)
291
glRectf(sx, rect[1], ex, rect[3])
293
color= text_colors[i%len(text_colors)]
294
apply(glColor3f, color)
296
if (type(d)==StringType):
298
if (align=='left'): glRasterPos2f(sx+3, rect[1]+5)
299
elif (align=='center'): glRasterPos2f((sx+ex)/2 - str_width/2 +3, rect[1]+5)
300
elif (align=='right'): glRasterPos2f(ex - str_width -3, rect[1]+5)
304
d(map(int,[sx, rect[1], ex, rect[3]]))
308
black= (0.0, 0.0, 0.0)
309
white= (1.0, 1.0, 1.0)
312
gray0= (0.17, 0.17, 0.17)
313
gray1= (0.25, 0.25, 0.25)
314
gray2= (0.33, 0.33, 0.33)
315
gray3= (0.41, 0.41, 0.41)
316
gray4= (0.49, 0.49, 0.49)
317
gray5= (0.57, 0.57, 0.57)
318
gray6= (0.65, 0.65, 0.65)
320
cols= [[.3, 'left'], [.2, 'left'], [.4, 'right'], [.1, 'center']]
322
header= [size[0]+20, size[3]-60, size[2]-40, size[3]-40]
324
def sort_byname(co): Button("Name",SORT_BYNAME, co[0]+3, co[1], co[2]-co[0]-4, 19)
325
def sort_bytype(co): Button("Type",SORT_BYTYPE, co[0]+3, co[1], co[2]-co[0]-4, 19)
326
def sort_bydata(co): Button("Data",SORT_BYDATA, co[0]+3, co[1], co[2]-co[0]-4, 19)
328
row_draw(header, [sort_byname, sort_bytype, sort_bydata,'Link'], cols, [gray0, gray1], gray6)
331
table= [size[0]+20, size[1]+220, size[2]-40, size[3]-60]
333
table= [size[0]+20, size[1]+20, size[2]-40, size[3]-60]
336
items= (table[3]-table[1])/row_height
339
if (items>len(browselist)): items= len(browselist)
341
end= len(browselist)-items
343
# scr= Scrollbar(SCROLLBAR, table[2]+5, table[1], 20, table[3]-table[1], scr.val, 0.0, end, 0, "Page Up/Down scrolls list.")
346
row[1]= row[3]-row_height
347
start= browse_scrollstart
348
if (start+items>len(browselist)): items= len(browselist)-start
349
for i in range(items):
351
data= browselist[i][:]
353
if (i%2): colors= [gray1, gray2]
354
else: colors= [gray2, gray3]
356
# Strange pythonic code
357
def view_doc(co,num=i):
358
Button("Doc",VIEW_DOC+num, co[0]+3, co[1]+2, co[2]-co[0]-4, 19)
360
def browse_module(co,num=i):
361
Button("Browse",BROWSE_MODULE+num, co[0]+3, co[1]+2, co[2]-co[0]-4, 19)
363
if (data[1]=='Function'):
369
data[2]= 'NO DOC STRING'
372
if (data[1]=='Module'): data[3]= browse_module
377
row_draw(row, data, cols, colors, tcolor)
379
row[1]= row[1]-row_height
380
row[3]= row[3]-row_height
383
table= [size[0]+20, size[1]+20, size[2]-40, size[1]+180]
385
apply(glColor3f, gray5)
386
glRectf(table[0], table[3], table[2], table[3]+20)
387
apply(glColor3f, gray2)
388
glRectf(table[0], table[1], table[2], table[3])
390
apply(glColor3f, black)
391
glRasterPos2f(table[0]+3, table[3]+5)
392
Text("Function: " + browsing.val + "." + browselist[selected][0])
394
Button("Close", CLOSE_VIEW, table[2]-50, table[3], 45, 18)
397
view_lines= int((table[3]-table[1])/row_height)-1
399
lines= split(browselist[selected][3], "\n")
400
doc_lines= len(lines)
402
sindex= view_lines*selected_page
403
eindex= view_lines*(selected_page+1)
408
lines= lines[sindex:eindex]
412
glRasterPos2f(table[0]+3, y)
417
if (sindex): Button("Page up", DOC_PAGE_UP, table[2]-100, table[3]-20, 90, 18)
418
if (eindex<doc_lines): Button("Page down", DOC_PAGE_DOWN, table[2]-100, table[1]+5, 90, 18)
423
global browse_scrollstart, browselist
424
if (browse_scrollstart<0): browse_scrollstart= 0
425
elif (browse_scrollstart>=len(browselist)): browse_scrollstart= len(browselist)-1
428
global browse_scrollstart
430
if (evt==QKEY or evt==ESCKEY): Exit()
432
if (evt in [PAGEUPKEY, PAGEDOWNKEY]):
433
if (evt==PAGEUPKEY): browse_scrollstart= browse_scrollstart-5
434
else: browse_scrollstart= browse_scrollstart+5
435
elif (evt in [UPARROWKEY, WHEELUPMOUSE]):
436
browse_scrollstart -= 1
437
elif (evt in [DOWNARROWKEY, WHEELDOWNMOUSE]):
438
browse_scrollstart += 1
445
if (evt==BROWSE_EVT): make_browselist()
447
elif (evt==SORT_BYNAME): sort_browselist(1)
448
elif (evt==SORT_BYTYPE): sort_browselist(2)
449
elif (evt==SORT_BYDATA): sort_browselist(3)
451
elif (evt==DOC_PAGE_UP): view_page(-1)
452
elif (evt==DOC_PAGE_DOWN): view_page(1)
454
elif (evt==BACK_MODULE): browse_module(-1)
455
elif (evt==CLOSE_VIEW): view_doc(-1)
456
elif (evt==FILTER_DISPLAY): toggle_function_filter()
458
#elif (evt==SCROLLBAR):
459
# global browse_scrollstart
460
# browse_scrollstart= int(scr.val)
462
elif (evt>=BROWSE_MODULE): browse_module(evt-BROWSE_MODULE)
463
elif (evt>=VIEW_DOC): view_doc(evt-VIEW_DOC)
467
Register(draw, event, bevent)