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