4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2008 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation
26 * ***** END GPL LICENSE BLOCK *****
32 #include "DNA_color_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_oops_types.h"
35 #include "DNA_space_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_screen_types.h"
38 #include "DNA_space_types.h"
39 #include "DNA_texture_types.h"
40 #include "DNA_vec_types.h"
41 #include "DNA_windowmanager_types.h"
43 #include "MEM_guardedalloc.h"
45 #include "BLI_blenlib.h"
46 #include "BLI_arithb.h"
49 #include "BKE_colortools.h"
50 #include "BKE_global.h"
51 #include "BKE_screen.h"
52 #include "BKE_texture.h"
53 #include "BKE_utildefines.h"
56 #include "ED_screen.h"
62 #include "BIF_glutil.h"
64 #include "UI_interface.h"
66 #include "UI_resources.h"
67 #include "UI_view2d.h"
69 #include "RNA_access.h"
70 #include "RNA_types.h"
72 #include "outliner_intern.h"
74 #define SET_INT_IN_POINTER(i) ((void*)(intptr_t)(i))
75 #define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i))
78 #define COLUMN_WIDTH 150
80 typedef void (*uiTableCellFunc)(void *userdata, int row, int col, struct rcti *rct, struct uiBlock *block);
82 typedef struct uiTable {
86 uiTableCellFunc cellfunc;
90 uiTable *UI_table_create(int rows, int cols, rcti *rct, uiTableCellFunc cellfunc, void *userdata)
94 table= MEM_callocN(sizeof(uiTable), "uiTable");
96 table->cellfunc= cellfunc;
99 table->userdata= userdata;
104 void UI_table_free(uiTable *table)
109 void UI_table_draw(const bContext *C, uiTable *table)
116 v2d= &C->region->v2d;
119 block= uiBeginBlock(C, C->region, "table outliner", UI_EMBOSST, UI_HELV);
121 for(y=rct->ymax, row=0; y>rct->ymin; y-=ROW_HEIGHT, row++) {
123 UI_ThemeColorShade(TH_BACK, 6);
124 glRecti(v2d->cur.xmin, y-ROW_HEIGHT, v2d->cur.xmax, y);
127 if(row >= table->rows)
130 for(col=0; col<table->cols; col++) {
131 cellrct.xmin= rct->xmin+COLUMN_WIDTH*col + 1;
132 cellrct.xmax= rct->xmin+COLUMN_WIDTH*(col+1);
133 cellrct.ymin= y-ROW_HEIGHT;
136 table->cellfunc(table->userdata, row, col, &cellrct, block);
140 UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
142 for(col=0; col<table->cols; col++)
143 fdrawline(rct->xmin+COLUMN_WIDTH*(col+1), rct->ymin, rct->xmin+COLUMN_WIDTH*(col+1), rct->ymax);
145 uiEndBlock(C, block);
150 /* ************************ main outliner area region *********************** */
152 typedef struct CellRNA {
159 CollectionPropertyIterator iter;
162 static void rna_back_cb(bContext *C, void *arg_unused, void *arg_unused2)
164 SpaceOops *soutliner= C->area->spacedata.first;
167 newpath= RNA_path_back(soutliner->rnapath);
168 if(soutliner->rnapath)
169 MEM_freeN(soutliner->rnapath);
170 soutliner->rnapath= newpath;
173 static void rna_pointer_cb(bContext *C, void *arg_prop, void *arg_index)
175 SpaceOops *soutliner= C->area->spacedata.first;
176 PropertyRNA *prop= arg_prop;
178 int index= GET_INT_FROM_POINTER(arg_index);;
180 newpath= RNA_path_append(soutliner->rnapath, NULL, prop, index, NULL);
181 if(soutliner->rnapath)
182 MEM_freeN(soutliner->rnapath);
183 soutliner->rnapath= newpath;
186 static void rna_label(CellRNA *cell, rcti *rct, uiBlock *block)
188 PropertySubType subtype;
191 char *vectoritem[4]= {"x", "y", "z", "w"};
192 char *quatitem[4]= {"w", "x", "y", "z"};
193 char *coloritem[4]= {"r", "g", "b", "a"};
198 type= RNA_property_type(&cell->ptr, prop);
199 subtype= RNA_property_subtype(&cell->ptr, prop);
200 arraylength= RNA_property_array_length(&cell->ptr, prop);
202 if(cell->index == -1) {
203 uiDefBut(block, LABEL, 0, (char*)RNA_property_ui_name(&cell->ptr, prop), rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, (char*)RNA_property_ui_description(&cell->ptr, prop));
205 else if (type != PROP_COLLECTION) {
206 if(arraylength == 4 && subtype == PROP_ROTATION)
207 sprintf(item, " %s", quatitem[cell->index]);
208 else if(arraylength <= 4 && (subtype == PROP_VECTOR || subtype == PROP_ROTATION))
209 sprintf(item, " %s", vectoritem[cell->index]);
210 else if(arraylength <= 4 && subtype == PROP_COLOR)
211 sprintf(item, " %s", coloritem[cell->index]);
213 sprintf(item, " %d", cell->index+1);
215 uiDefBut(block, LABEL, 0, item, rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, "");
219 static void rna_collection_but(CellRNA *cell, rcti *rct, uiBlock *block)
223 PropertyRNA *nameprop;
224 char name[256]= "", *nameptr= name;
226 RNA_property_collection_lookup_int(&cell->ptr, cell->prop, cell->index, &lookup);
229 nameprop= RNA_struct_name_property(&lookup);
232 nameptr= RNA_property_string_get_alloc(&lookup, nameprop, name, sizeof(name));
234 sprintf(nameptr, "%d", cell->index+1);
237 but= uiDefBut(block, BUT, 0, nameptr, rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, "");
238 uiButSetFlag(but, UI_TEXT_LEFT);
243 uiButSetFunc(but, rna_pointer_cb, cell->prop, SET_INT_IN_POINTER(cell->index));
246 static void rna_but(CellRNA *cell, rcti *rct, uiBlock *block)
251 int arraylength, index;
254 type= RNA_property_type(&cell->ptr, prop);
255 arraylength= RNA_property_array_length(&cell->ptr, prop);
257 if(type == PROP_COLLECTION) {
258 /* item in a collection */
260 rna_collection_but(cell, rct, block);
264 index= (arraylength)? cell->index: 0;
267 but= uiDefRNABut(block, 0, &cell->ptr, prop, index, rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin);
269 if(type == PROP_POINTER)
270 uiButSetFunc(but, rna_pointer_cb, prop, SET_INT_IN_POINTER(0));
275 static void rna_path_but(CellRNA *cell, rcti *rct, uiBlock *block)
279 but= uiDefBut(block, BUT, 0, (cell->space->rnapath)? "..": ".", rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, "");
280 uiButSetFlag(but, UI_TEXT_LEFT);
281 uiButSetFunc(but, rna_back_cb, cell->space, NULL);
284 static void rna_table_cell_func(void *userdata, int row, int col, rcti *rct, uiBlock *block)
286 CellRNA *cell= userdata;
293 rna_path_but(cell, rct, block);
298 /* set next property for new row */
299 if(row != cell->lastrow) {
303 type= RNA_property_type(&cell->ptr, cell->prop);
304 if(type == PROP_COLLECTION)
305 length= RNA_property_collection_length(&cell->ptr, cell->prop);
307 length= RNA_property_array_length(&cell->ptr, cell->prop);
309 /* verify if we need to go to the next property */
310 if(type == PROP_COLLECTION && cell->index < length);
311 else if(length && cell->index < length);
313 RNA_property_collection_next(&cell->iter);
314 cell->prop= cell->iter.ptr.data;
320 cell->prop= cell->iter.ptr.data;
329 rna_label(cell, rct, block);
331 rna_but(cell, rct, block);
334 static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
336 UI_view2d_size_update(&ar->v2d, ar->winx, ar->winy);
340 static void outliner_main_area_draw(const bContext *C, ARegion *ar)
345 PropertyRNA *prop, *iterprop;
348 int rows, cols, awidth, aheight, width, height;
349 SpaceOops *soutliner= C->area->spacedata.first;
350 View2D *v2d= &ar->v2d;
351 View2DScrollers *scrollers;
354 UI_GetThemeColor3fv(TH_BACK, col);
355 glClearColor(col[0], col[1], col[2], 0.0);
356 glClear(GL_COLOR_BUFFER_BIT);
358 awidth= width= ar->winx;
359 aheight= height= ar->winy;
362 cell.space= soutliner;
364 RNA_main_pointer_create(G.main, &cell.ptr);
367 /* solve RNA path or reset if fails */
368 if(soutliner->rnapath) {
369 if(!RNA_path_resolve(&cell.ptr, soutliner->rnapath, &newptr, &prop)) {
371 printf("RNA outliner: failed resolving path. (%s)\n", soutliner->rnapath);
374 if(newptr.data && newptr.type) {
378 MEM_freeN(soutliner->rnapath);
379 soutliner->rnapath= NULL;
383 /* compute number of rows and columns */
387 iterprop= RNA_struct_iterator_property(&cell.ptr);
388 RNA_property_collection_begin(&cell.ptr, iterprop, &cell.iter);
390 for(; cell.iter.valid; RNA_property_collection_next(&cell.iter)) {
391 prop= cell.iter.ptr.data;
393 rows += 1 + RNA_property_array_length(&cell.ptr, prop);
394 if(RNA_property_type(&cell.ptr, prop) == PROP_COLLECTION)
395 rows += RNA_property_collection_length(&cell.ptr, prop);
398 RNA_property_collection_end(&cell.iter);
400 /* determine extents of data
401 * - height must be at least the height of the mask area
402 * - width is columns + 1, as otherwise, part of last column
403 * will be obscured by scrollers
405 if ((rows*ROW_HEIGHT) > height)
406 height= rows * ROW_HEIGHT;
407 width= (cols + 1) * COLUMN_WIDTH;
409 /* update size of tot-rect (extents of data/viewable area) */
410 UI_view2d_totRect_set(v2d, width, height);
417 /* set matrix for 2d-view controls */
418 UI_view2d_view_ortho(C, v2d);
420 /* create and draw table */
421 table= UI_table_create(rows, 2, &rct, rna_table_cell_func, &cell);
423 RNA_property_collection_begin(&cell.ptr, iterprop, &cell.iter);
424 UI_table_draw(C, table);
425 RNA_property_collection_end(&cell.iter);
427 UI_table_free(table);
429 /* reset view matrix */
430 UI_view2d_view_restore(C);
433 scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
434 UI_view2d_scrollers_draw(C, v2d, scrollers);
435 UI_view2d_scrollers_free(scrollers);
438 static void outliner_main_area_free(ARegion *ar)
442 /* ************************ header outliner area region *********************** */
445 static void outliner_header_area_draw(const bContext *C, ARegion *ar)
447 SpaceOops *soutliner= C->area->spacedata.first;
453 path= (soutliner->rnapath)? soutliner->rnapath: "Main";
455 if(ED_screen_area_active(C))
456 UI_GetThemeColor3fv(TH_HEADER, col);
458 UI_GetThemeColor3fv(TH_HEADERDESEL, col);
460 glClearColor(col[0], col[1], col[2], 0.0);
461 glClear(GL_COLOR_BUFFER_BIT);
463 width= ar->winrct.xmax - ar->winrct.xmin;
464 height= ar->winrct.ymax - ar->winrct.ymin;
467 UI_GetBoundingBox(UI_HELV, path, 0, &bbox);
469 glColor3f(1.0f, 1.0f, 1.0f);
471 UI_RasterPos(0.5f*(width - (bbox.xmax - bbox.xmin)), 0.5f*(height - (bbox.ymax - bbox.ymin)));
472 UI_DrawString(UI_HELV, path, 0);
475 static void outliner_header_area_free(ARegion *ar)
479 /* ******************** default callbacks for outliner space ***************** */
481 static SpaceLink *outliner_new(void)
483 SpaceOops *soutliner;
485 soutliner= MEM_callocN(sizeof(SpaceOops), "initoutliner");
487 return (SpaceLink*)soutliner;
490 /* not spacelink itself */
491 static void outliner_free(SpaceLink *sl)
493 SpaceOops *soutliner= (SpaceOops*)sl;
495 if(soutliner->rnapath) {
496 MEM_freeN(soutliner->rnapath);
497 soutliner->rnapath= NULL;
501 /* spacetype; init callback */
502 static void outliner_init(wmWindowManager *wm, ScrArea *sa)
507 static SpaceLink *outliner_duplicate(SpaceLink *sl)
509 SpaceOops *soutliner= (SpaceOops *)sl;
510 SpaceOops *soutlinern= MEM_dupallocN(soutliner);
512 if(soutlinern->rnapath)
513 soutlinern->rnapath= MEM_dupallocN(soutlinern->rnapath);
515 return (SpaceLink *)soutlinern;
518 /* only called once, from screen/spacetypes.c */
519 void ED_spacetype_outliner(void)
521 SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype time");
524 st->spaceid= SPACE_OOPS;
525 strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
527 st->new= outliner_new;
528 st->free= outliner_free;
529 st->init= outliner_init;
530 st->duplicate= outliner_duplicate;
531 st->operatortypes= outliner_operatortypes;
532 st->keymap= outliner_keymap;
534 /* regions: main window */
535 art= MEM_callocN(sizeof(ARegionType), "spacetype time region");
536 art->regionid = RGN_TYPE_WINDOW;
537 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
539 art->init= outliner_main_area_init;
540 art->draw= outliner_main_area_draw;
541 art->free= outliner_main_area_free;
542 BLI_addhead(&st->regiontypes, art);
544 /* regions: header */
545 art= MEM_callocN(sizeof(ARegionType), "spacetype time region");
546 art->regionid = RGN_TYPE_HEADER;
547 art->minsizey= HEADERY;
548 art->keymapflag= ED_KEYMAP_UI;
550 art->draw= outliner_header_area_draw;
551 art->free= outliner_header_area_free;
552 BLI_addhead(&st->regiontypes, art);
554 BKE_spacetype_register(st);