Merge branch 'blender2.7'
[blender.git] / doc / guides / interface_API.txt
1 ---------------------------------------------------
2 Blender interface.c API toolkit notes
3 (july 2003, Ton Roosendaal)
4 ---------------------------------------------------
5
6 Contents
7
8 1 General notes
9 1.1 C and H files
10
11 2. Windows & Blocks 
12 2.1 Memory allocation
13 2.2 And how it works internally
14
15 3. API for uiBlock
16 3.1 uiBlock Controlling functions
17 3.2 Internal function to know
18
19 4. API for uiButton 
20 4.1 UiDefBut
21         1. BUT
22         2. TOG or TOGN
23            TOG|BIT|<nr>
24         3. ROW
25         4. NUMSLI or HSVSLI
26         5. NUM
27         6. TEX
28         7. LABEL
29         8  SEPR
30         9. MENU
31         10.     COL
32 4.2 Icon buttons
33 4.3 pulldown menus / block buttons
34         14. BLOCK
35 4.4 specials
36         15. KEYEVT
37         16. LINK and INLINK
38 4.5 uiButton control functions
39
40
41 ----------------1. General notes
42
43 - The API is built with Blender in mind, with some buttons acting on lists of Blender data.
44   It was not meant to be available as a separate SDK, nor to be used for other applications.
45   
46 - It works with only OpenGL calls, for the full 100%. This means that it has some quirks
47   built-in to work with all OS's and OpenGL versions. Especially frontbuffer drawing is 
48   a continuous point of attention. Buttons can be drawn with any window matrix. However,
49   errors can still occur when buttons are created in windows with non-standard glViewports.
50   
51 - The code was written to replace the old 1.8 button system, but under high pressure. Quite
52   some button methods from the old system were copied for that reason.
53   
54 - I tried to design a unified GUI system, which equally works for pulldown menus, pop up menus,
55   and normal button layouts. Although it gives nice features and freedom in design, the code 
56   looks quite hard to understand for that reason. Not all 'normal' pulldown menu features 
57   could be hacked in easily, they just differ too much from other UI elements. Could be 
58   looked at once...
59   
60 - During the past period of NaN (beginning of 2002) someone tried to make a more 'high' level
61   API for it, with less low level defines and structure info needed in calling code. I am not 
62   really sure if this was done well... or even finished. In the bottom of interface.c you can
63   see the 'new' API which is now used in Blender code. It used to be so much more simple!
64   Nevertheless, I will use that convention in this doc.
65
66 - Unfinished stuff: the code was scheduled to be expanded with 'floating blocks' which can
67   serve as permanent little button-fields in Blender windows. Think for example of having
68   an (optional) extra field in the 3d window displaying object loc/rot/size.
69   After that, the existing button windows can be reorganized in such blocks as well, allowing
70   a user to configure the genereal buttons layout (make vertical for example).
71   
72
73 --------------1.1 C and H files
74
75 blender/source/blender/src/interface.c  /* almost all code */
76 blender/source/blender/include/interface.h      /* internals for previous code */
77 blender/source/blender/include/BIF_interface.h  /* externals for previous code */
78
79 (the previous 2 include files have not been separated fully yet)
80
81 Color and icons stuff has been put in: (unfinished code, under development)
82 blender/source/blender/src/resources.c 
83 blender/source/blender/include/BIF_resources.h
84
85 Related code:
86 blender/source/blender/src/toolbox.c (extra GUI elements built on top of this API)
87
88
89 --------------2. Windows & Blocks 
90
91 All GUI elements are collected in uiBlocks, which in turn are linked together in a list that's 
92 part of a Blender Area-window.
93
94         uiBlock *block = uiNewBlock(&curarea->uiblocks, "stuff", UI_EMBOSSX, UI_HELV, curarea->win);
95
96 The next code example makes a new block, and puts it in the list of blocks of the current active 
97 Area:
98
99         uiDoBlocks(&curarea->uiblocks, event);
100
101 This code is usually available in each area-window event queue handler. You give uiDoBlocks
102 an event code, and the uiDoBlocks handles whatever is to be handled. Blocks can be 
103 standard buttons or pull down menus. Can return immediately, or jump to an internal handling 
104 loop.
105
106 2.1 Memory allocation
107
108 Important to know is that for this toolkit there's no difference in "creating blocks" or 
109 "drawing blocks". In fact, for each window redraw all blocks are created again. Constructing 
110 button interfaces in Blender always happens in the main drawing function itself.
111
112 Memory allocation is handled as follows:
113 - if in this window a uiBlock with the same name existed, it is freed
114 - when you close a window (or blender) the uiBlocks get freed.
115 - when you duplicate (split) a window, the uiBlocks get copied
116
117 2.2 And how it works internally
118
119 With a call to uiDoblocks, all blocks in the current active window are evaluated.
120 It walks through the lists in a rather complex manner:
121
122 - while(looping)
123
124         /* the normal buttons handling */
125         - for each block
126                 - call uiDoBlock (handles buttons for single block)
127         - (end for)
128         
129         /* at this moment, a new block can be created, for a menu */
130         /* so we create a 2nd loop for it */
131         - while first block is a menu
132                 - if block is a menu and not initialized: 
133                         - initialize 'saveunder'
134                         - draw it 
135                 - get event from queue
136                 - call uiDoBlock (handles buttons for single block)
137                 /* here, a new block again can be created, for a sub menu */
138                 - if return "end" from uiDoBlock
139                         restore 'saveunder's
140                         free all menu blocks
141                         exit from loop
142                 - do tooltip if nothing has happened
143         - (end while)
144         
145         - if there was menu, it does this loop once more
146           (when you click outside a menu, at another button)
147         
148 - (end while)
149
150 - do tooltip if nothing has happened
151
152
153
154 -------------3. API for uiBlock 
155
156 Create a new buttons block, and link it to the window:
157
158 uiBlock *uiNewBlock(ListBase *lb, char *name, short dt, short font, short win)
159         ListBase *lb    pointer to list basis, where the block will be appended to (blenlib)
160         char *name              unique name to identify the block. When the name exists in the list,
161                                         the old uiBlock gets freed.
162         short dt                drawtype. See below
163         short font              font id number
164         short win               blender area-window id
165
166 drawtype:
167         UI_EMBOSSX              0       /* Rounded embossed button (standard in Blender) */
168         UI_EMBOSSW              1       /* Simpler embossed button */
169         UI_EMBOSSN              2       /* Button with no border */
170         UI_EMBOSSF              3       /* Square embossed button (file select) */
171         UI_EMBOSSM              4       /* Colored, for pulldown menus */
172         UI_EMBOSSP              5       /* Simple borderless colored button (like blender sensors) */
173
174 font:
175         UI_HELV                 0       /* normal font */
176         UI_HELVB                1       /* bold font */
177 With the new truetype option in Blender, this is used for all font families
178
179 When a uiBlock is created, each uiButton that is defined gets the uiBlock properties.
180 Changing Block properties in between will affact uiButtons defined thereafter.
181
182
183
184 ----------3.1 uiBlock Controlling functions:
185
186 void uiDrawBlock(block) 
187         draws the block
188
189 void uiBlockSetCol(uiBlock *block, int col)     
190
191 col:
192         BUTGREY,
193         BUTGREEN,
194         BUTBLUE,
195         BUTSALMON,
196         MIDGREY,
197         BUTPURPLE,
198
199 void uiBlockSetEmboss(uiBlock *block, int emboss)
200         changes drawtype
201
202 void uiBlockSetDirection(uiBlock *block, int direction) 
203         for pop-up and pulldown menus:
204
205 direction:
206         UI_TOP  
207         UI_DOWN 
208         UI_LEFT 
209         UI_RIGHT
210
211 void uiBlockSetXOfs(uiBlock *block, int xofs)
212         for menus, offset from parent
213
214 void uiBlockSetButmFunc(uiBlock *block, void (*menufunc)(void *arg, int event), void *arg)
215         sets function to be handled when a menu-block is marked "OK"
216         
217 void uiAutoBlock(uiBlock *block, float minx, float miny, float sizex, float sizey, UI_BLOCK_ROWS)
218
219         Sets the buttons in this block to automatically align, and fit within boundaries. 
220         Internally it allows multiple columns or rows as well. Only 'row order' has been implemented.
221         The uiDefBut definitions don't need coordinates as input here, but instead:
222         - first value (x1) to indicate row number
223         - width and height values (if filled in) will be used to define a relative width/height.
224         A call to uiDrawBlock will invoke the calculus to fit in all buttons.
225
226
227
228 ---------- 3.2 Internal function to know:
229
230 These flags used to be accessible from outside of interface.c. Currently it is only
231 used elsewhere by toolbox.c, so it can be considered 'internal' somewhat.
232
233 void uiBlockSetFlag(uiBlock *block, int flag)   /* block types, can be 'OR'ed */
234         UI_BLOCK_LOOP           1               a sublooping block, drawn in frontbuffer, i.e. menus
235         UI_BLOCK_REDRAW         2               block needs a redraw
236         UI_BLOCK_RET_1          4               block is closed when an event happens with value '1' (press key, not for mouse)
237         UI_BLOCK_BUSY           8               internal
238         UI_BLOCK_NUMSELECT      16              keys 1-2-...-9-0 can be used to select items
239         UI_BLOCK_ENTER_OK       32              enter key closes block with "OK"
240         
241 (these values are being set within the interface.c and toolbox.c code.)
242
243
244 -------------4. API for uiButton 
245
246 In Blender a button can do four things:
247
248 - directly visualize data, and write to it.
249 - put event codes (shorts) back in the queue, to be handled
250 - call a user-defined function pointer (while being pressed, etc)
251 - create and call another block (i.e. menu)
252
253 Internally, each button or menu item is a 'uiButton', with a generic API and handling:
254 ui_def_but(block, type, retval, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip);
255
256 Because a lot of obscure generic (re-use) happens here, translation calls have been made
257 for each most button types individually.
258
259
260 -----------4.1 UiDefBut
261
262 uiBut *UiDefBut[CSIF](  uiBlock *block, int type, int retval, char *str, 
263                                 short x1, short y1, short x2, short y2, xxxx *poin, 
264                                 float min, float max, float a1, float a2,  char *tip)
265
266 UiDefButC       operatates on char
267 UiDefButS       operatates on short
268 UiDefButI       operatates on int
269 UiDefButF       operatates on float
270
271 *block:         current uiBlock pointer
272 type:           see below
273 retval:         return value, which is put back in queue
274 *str:           button name
275 x1, y1:         coordinates of left-lower corner
276 x2, y2:         width, height
277 *poin:          pointer to char, short, int, float
278 min, max        used for slider buttons
279 a1, a2          extra info for some buttons
280 *tip:           tooltip string
281
282 type:
283
284 1. BUT
285         Activation button. (like "Render")
286         Passing on a pointer is not needed
287         
288 2. TOG or TOGN
289         Toggle button (like "Lock")
290         The pointer value is set either at 0 or 1
291         If pressed, it calls the optional function with arguments provided.
292         Type TOGN: works negative, when pressed it sets at 0
293
294         "|BIT|<nr>"
295         When added to type, it works on a single bit <nr> (lowest order bit: nr = '0')
296
297 3. ROW
298         Button that's part of a row. 
299         in "min" you set a row-id number, in "max" the value you want *poin to be
300         assigned when you press the button. Always pass on these values as floats.
301         When this button is pressed, it sets the "max" value to *poin, and redraws
302         all buttons with the same row-id number.
303
304 4. NUMSLI or HSVSLI
305         Number-slider or hsv-slider button.
306         "min" and "max" are to clamp the value to.
307         If you want a button type "Col" to be updated, make 'a1' equal to 'retval'
308         from the COL button.
309         
310 5. NUM
311         Number button
312         Set the clamping values 'min' and 'max' always as float.
313         For UiDefButF, set a 'step' in 'a1', in 1/100's. The step value is the increment or
314         decrement when you click once on the right or left side of a button.
315         The optional button function is additionally called for each change of the *poin value.
316         
317 6. TEX
318         Text string button.
319         Pointertype is standard a char. Value 'max' is length of string (pass as float).
320         When button is left with ESC, it doesn't put the 'retval' at the queue.
321         
322 7. LABEL
323         Label button.
324         Only displays text. 
325         If 'min' is set at 1.0, the text is printed in white.
326         
327 8  SEPR
328         A separator line, typically used within pulldown menus.
329         
330 9. MENU
331         Menu button.
332         The syntax of the string in *name defines the menu items:
333                 - %t means the previous text becomes the title
334                 - item separator is '|'
335                 - return values are indicated with %x[nr] (i.e: %x12). 
336                         without returnvalues, the first item gets value 0 (incl. title!)
337         Example: "Do something %t| turn left %2| turn right %1| nothing %0"
338         
339 10.     COLOR
340         A special button that only visualizes a RGB value
341         In 'retval' you can put a code, which is used to identify for sliders if it needs
342         redraws while using the sliders. Check button '5'.
343         As *poin you input the pointer to the 'r' value, 'g' and 'b' are supposed to be
344         next to that. 
345
346
347 ------------4.2 Icon buttons
348
349 Instead of a 'name', all buttons as described for uiDefBut also can have an icon:
350
351 uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, 
352                         short x1, short y1, short x2, short y2, void *poin, 
353                         float min, float max, float a1, float a2,  char *tip)
354
355         Same syntax and types available as previous uiDefBut, but now with an icon code 
356         instead of a name. The icons are numbered in resources.c
357
358 uiBut *uiDefIconTextButF(uiBlock *block, int type, int retval, int icon, char *str, 
359                         short x1, short y1, short x2, short y2, float *poin, 
360                         float min, float max, float a1, float a2,  char *tip)
361
362         Same again, but now with an icon and string as button name.
363
364
365 -----------4.3 pulldown menus / block buttons
366
367 14. BLOCK
368 void uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, char *str, 
369         short x1, short y1, short x2, short y2, char *tip)
370
371         This button creates a new block when pressed. The function argument 'func' is called
372         to take care of this. An example func:
373         
374         static uiBlock *info_file_importmenu(void *arg_unused)
375         {
376                 uiBlock *block;
377                 short yco = 0, xco = 20;
378         
379                 block = uiNewBlock(&curarea->uiblocks, "importmenu", UI_EMBOSSW, UI_HELV, G.curscreen->mainwin);
380                 uiBlockSetXOfs(block, -40);  // offset to parent button
381         
382                 /* flags are defines */
383                 uiDefBut(block, LABEL, 0, "VRML 2.0 options", xco, yco, 125, 19, NULL, 0.0, 0.0, 0, 0, "");
384                 uiDefButS(block, TOG|BIT|0, 0, "SepLayers", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, "");
385                 uiDefButS(block, TOG|BIT|1, 0, "Scale 1/100", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, "");
386                 uiDefButS(block, TOG|BIT|2, 0, "Two Sided", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, "");
387         
388                 uiBlockSetDirection(block, UI_RIGHT);
389                 uiTextBoundsBlock(block, 50);  /* checks for fontsize */
390
391                 return block;
392         }
393
394         The uiDef coordinates here are only relative. When this function is called, the interface 
395         code automatically makes sure the buttons fit in the menu nicely. 
396         
397         Inside a menu uiBlock, other uiBlocks can be invoked to make a hierarchical menu.
398
399
400
401 -----------4.4 specials
402
403 15. KEYEVT
404
405 void uiDefKeyevtButS(uiBlock *block, int retval, char *str, 
406                 short x1, short y1, short x2, short y2, short *spoin, char *tip)
407
408         A special button, which stores a keyvalue in *spoin. When the button is pressed,
409         it displays the text 'Press any Key'. A keypress then stores the value.
410         
411 16. LINK and INLINK
412
413         These button present a method of linking data in Blender, by drawing a line from one
414         icon to another. It consists of two button types:
415         
416         LINK, the 'linking from' part, can be:
417         - a single pointer to data (only one line allowed)
418         - an array of pointers to data. The LINK buttons system  keeps track of allocating 
419           space for the array, and set the correct pointers in it.
420         
421         INLINK, the 'linking to' part activates creating a link, when a user releases the mouse 
422         cursor over it, while dragging a line from the LINK button.
423         
424         These buttons are defined as follows:
425         
426                 
427 uiBut but= uiDefIconBut(block, LINK, 0, ICON_LINK,      x1, y1, w, h, NULL, 0, 0, 0, 0, "");
428         /* create the LINK icon */
429
430 uiSetButLink(but, void **pt, void ***ppt, short *totlink, short fromcode, short tocode);
431         **pt: pointer to pointer (only one link allowed)
432         ***ppt: pointer to pointerpointer (an array of pointers)
433         (Either one of these values should be NULL)
434         
435         fromcode: (currently unused)
436         tocode: a short indicating which blocks it can link to. 
437         
438         
439 uiDefIconBut(block, INLINK, 0, ICON_INLINK, x1, y1, w, h, void *poin, short fromcode, 0, 0, 0, "");
440         poin: the pointer of the datablock you want to create links to
441         fromcode: a short identifying which LINK buttons can connect to it                        
442         
443
444
445 ------------- 4.5 uiButton control functions
446
447
448 void uiButSetFunc(uiBut *but, void (*func)(void *arg1, void *arg2), void *arg1, void *arg2)
449         When the button is pressed and released, it calls this function, with the 2 arguments.
450
451 void uiButSetFlag(uiBut *but, int flag)
452         set a flag for further control of button behaviour:
453         flag:
454         UI_TEXT_LEFT
455         
456 int uiButGetRetVal(uiBut *but)
457         gives return value
458
459
460 </body>
461 <br><br><br>