replace fixed sizes with sizeof when passing string length since size wasn't always...
[blender.git] / source / blender / editors / space_outliner / space_outliner.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_outliner/space_outliner.c
28  *  \ingroup spoutliner
29  */
30
31
32 #include <string.h>
33 #include <stdio.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_blenlib.h"
38 #include "BLI_math.h"
39 #include "BLI_rand.h"
40 #include "BLI_utildefines.h"
41
42 #include "BKE_context.h"
43 #include "BKE_screen.h"
44
45 #include "ED_space_api.h"
46 #include "ED_screen.h"
47
48 #include "WM_api.h"
49 #include "WM_types.h"
50
51 #include "BIF_gl.h"
52
53 #include "UI_resources.h"
54 #include "UI_view2d.h"
55
56
57 #include "outliner_intern.h"
58
59 static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
60 {
61         wmKeyMap *keymap;
62         
63         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
64         
65         /* own keymap */
66         keymap= WM_keymap_find(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0);
67         /* don't pass on view2d mask, it's always set with scrollbar space, hide fails */
68         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, &ar->winrct);
69 }
70
71 static void outliner_main_area_draw(const bContext *C, ARegion *ar)
72 {
73         View2D *v2d= &ar->v2d;
74         View2DScrollers *scrollers;
75         
76         /* clear */
77         UI_ThemeClearColor(TH_BACK);
78         glClear(GL_COLOR_BUFFER_BIT);
79         
80         draw_outliner(C);
81         
82         /* reset view matrix */
83         UI_view2d_view_restore(C);
84         
85         /* scrollers */
86         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
87         UI_view2d_scrollers_draw(C, v2d, scrollers);
88         UI_view2d_scrollers_free(scrollers);
89 }
90
91
92 static void outliner_main_area_free(ARegion *UNUSED(ar))
93 {
94         
95 }
96
97 static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn)
98 {
99         /* context changes */
100         switch(wmn->category) {
101                 case NC_SCENE:
102                         switch(wmn->data) {
103                                 case ND_OB_ACTIVE:
104                                 case ND_OB_SELECT:
105                                 case ND_OB_VISIBLE:
106                                 case ND_OB_RENDER:
107                                 case ND_MODE:
108                                 case ND_KEYINGSET:
109                                 case ND_FRAME:
110                                 case ND_RENDER_OPTIONS:
111                                 case ND_LAYER:
112                                 case ND_WORLD:
113                                         ED_region_tag_redraw(ar);
114                                         break;
115                         }
116                         break;
117                 case NC_OBJECT:
118                         switch(wmn->data) {
119                                 case ND_TRANSFORM:
120                                         /* transform doesn't change outliner data */
121                                         break;
122                                 case ND_BONE_ACTIVE:
123                                 case ND_BONE_SELECT:
124                                 case ND_DRAW:
125                                 case ND_PARENT:
126                                 case ND_OB_SHADING:
127                                         ED_region_tag_redraw(ar);
128                                         break;
129                                 case ND_CONSTRAINT:
130                                         switch(wmn->action) {
131                                                 case NA_ADDED:
132                                                 case NA_REMOVED:
133                                                 case NA_RENAME:
134                                                         ED_region_tag_redraw(ar);
135                                                         break;
136                                         }
137                                         break;
138                                 case ND_MODIFIER:
139                                         /* all modifier actions now */
140                                         ED_region_tag_redraw(ar);
141                                         break;
142                         }
143                         break;
144                 case NC_GROUP:
145                         /* all actions now, todo: check outliner view mode? */
146                         ED_region_tag_redraw(ar);
147                         break;
148                 case NC_LAMP:
149                         /* For updating lamp icons, when changing lamp type */
150                         if(wmn->data == ND_LIGHTING_DRAW)
151                                 ED_region_tag_redraw(ar);
152                                 break;
153                 case NC_SPACE:
154                         if(wmn->data == ND_SPACE_OUTLINER)
155                                 ED_region_tag_redraw(ar);
156                                 break;
157                 case NC_ID:
158                         if(wmn->action == NA_RENAME)
159                                 ED_region_tag_redraw(ar);
160                         break;
161                 case NC_MATERIAL:
162                         switch(wmn->data) {
163                                 case ND_SHADING:
164                                 case ND_SHADING_DRAW:
165                                         ED_region_tag_redraw(ar);
166                                         break;
167                         }
168                         break;
169                 case NC_TEXTURE:
170                         ED_region_tag_redraw(ar);
171                         break;
172                 case NC_GEOM:
173                         switch(wmn->data) {
174                                 case ND_DATA:
175                                         /* needed for vertex groups only, no special notifier atm so use NC_GEOM|ND_DATA */
176                                         ED_region_tag_redraw(ar);
177                                         break;
178                         }
179                         break;
180                 case NC_ANIMATION:
181                         switch(wmn->data) {
182                                 case ND_NLA_ACTCHANGE:
183                                         ED_region_tag_redraw(ar);
184                                         break;
185                                 case ND_ANIMCHAN:
186                                         if(wmn->action==NA_SELECTED)
187                                                 ED_region_tag_redraw(ar);
188                                         break;
189                         }
190                         break;
191         }
192         
193 }
194
195
196 /* ************************ header outliner area region *********************** */
197
198 /* add handlers, stuff you only do once or on area/region changes */
199 static void outliner_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
200 {
201         ED_region_header_init(ar);
202 }
203
204 static void outliner_header_area_draw(const bContext *C, ARegion *ar)
205 {
206         ED_region_header(C, ar);
207 }
208
209 static void outliner_header_area_free(ARegion *UNUSED(ar))
210 {
211 }
212
213 static void outliner_header_area_listener(ARegion *ar, wmNotifier *wmn)
214 {
215         /* context changes */
216         switch(wmn->category) {
217                 case NC_SCENE:
218                         if(wmn->data == ND_KEYINGSET)
219                                 ED_region_tag_redraw(ar);
220                         break;
221                 case NC_SPACE:
222                         if(wmn->data == ND_SPACE_OUTLINER)
223                                 ED_region_tag_redraw(ar);
224                         break;
225         }
226 }
227
228 /* ******************** default callbacks for outliner space ***************** */
229
230 static SpaceLink *outliner_new(const bContext *UNUSED(C))
231 {
232         ARegion *ar;
233         SpaceOops *soutliner;
234
235         soutliner= MEM_callocN(sizeof(SpaceOops), "initoutliner");
236         soutliner->spacetype= SPACE_OUTLINER;
237         
238         /* header */
239         ar= MEM_callocN(sizeof(ARegion), "header for outliner");
240         
241         BLI_addtail(&soutliner->regionbase, ar);
242         ar->regiontype= RGN_TYPE_HEADER;
243         ar->alignment= RGN_ALIGN_BOTTOM;
244         
245         /* main area */
246         ar= MEM_callocN(sizeof(ARegion), "main area for outliner");
247         
248         BLI_addtail(&soutliner->regionbase, ar);
249         ar->regiontype= RGN_TYPE_WINDOW;
250         
251         ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
252         ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
253         ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
254         ar->v2d.keeptot= V2D_KEEPTOT_STRICT;
255         ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
256         
257         return (SpaceLink*)soutliner;
258 }
259
260 /* not spacelink itself */
261 static void outliner_free(SpaceLink *sl)
262 {
263         SpaceOops *soutliner= (SpaceOops*)sl;
264         
265         outliner_free_tree(&soutliner->tree);
266         if(soutliner->treestore) {
267                 if(soutliner->treestore->data) MEM_freeN(soutliner->treestore->data);
268                 MEM_freeN(soutliner->treestore);
269         }
270         
271 }
272
273 /* spacetype; init callback */
274 static void outliner_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
275 {
276         
277 }
278
279 static SpaceLink *outliner_duplicate(SpaceLink *sl)
280 {
281         SpaceOops *soutliner= (SpaceOops *)sl;
282         SpaceOops *soutlinern= MEM_dupallocN(soutliner);
283
284         soutlinern->tree.first= soutlinern->tree.last= NULL;
285         soutlinern->treestore= NULL;
286         
287         return (SpaceLink *)soutlinern;
288 }
289
290 /* only called once, from space_api/spacetypes.c */
291 void ED_spacetype_outliner(void)
292 {
293         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype time");
294         ARegionType *art;
295         
296         st->spaceid= SPACE_OUTLINER;
297         strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
298         
299         st->new= outliner_new;
300         st->free= outliner_free;
301         st->init= outliner_init;
302         st->duplicate= outliner_duplicate;
303         st->operatortypes= outliner_operatortypes;
304         st->keymap= outliner_keymap;
305         
306         /* regions: main window */
307         art= MEM_callocN(sizeof(ARegionType), "spacetype time region");
308         art->regionid = RGN_TYPE_WINDOW;
309         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
310         
311         art->init= outliner_main_area_init;
312         art->draw= outliner_main_area_draw;
313         art->free= outliner_main_area_free;
314         art->listener= outliner_main_area_listener;
315         BLI_addhead(&st->regiontypes, art);
316         
317         /* regions: header */
318         art= MEM_callocN(sizeof(ARegionType), "spacetype time region");
319         art->regionid = RGN_TYPE_HEADER;
320         art->prefsizey= HEADERY;
321         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
322         
323         art->init= outliner_header_area_init;
324         art->draw= outliner_header_area_draw;
325         art->free= outliner_header_area_free;
326         art->listener= outliner_header_area_listener;
327         BLI_addhead(&st->regiontypes, art);
328         
329         BKE_spacetype_register(st);
330 }
331