Rename any instance of scene layer or render layer in code with view layer
[blender.git] / source / blender / editors / space_buttons / space_buttons.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_buttons/space_buttons.c
28  *  \ingroup spbuttons
29  */
30
31 #include <string.h>
32 #include <stdio.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_blenlib.h"
37 #include "BLI_utildefines.h"
38
39 #include "BKE_context.h"
40 #include "BKE_screen.h"
41
42 #include "ED_space_api.h"
43 #include "ED_screen.h"
44
45 #include "WM_api.h"
46 #include "WM_types.h"
47
48 #include "RNA_access.h"
49
50 #include "buttons_intern.h"  /* own include */
51
52 /* ******************** default callbacks for buttons space ***************** */
53
54 static SpaceLink *buttons_new(const bContext *UNUSED(C))
55 {
56         ARegion *ar;
57         SpaceButs *sbuts;
58         
59         sbuts = MEM_callocN(sizeof(SpaceButs), "initbuts");
60         sbuts->spacetype = SPACE_BUTS;
61         sbuts->align = BUT_VERTICAL;
62
63         /* header */
64         ar = MEM_callocN(sizeof(ARegion), "header for buts");
65         
66         BLI_addtail(&sbuts->regionbase, ar);
67         ar->regiontype = RGN_TYPE_HEADER;
68         ar->alignment = RGN_ALIGN_TOP;
69         
70 #if 0
71         /* context region */
72         ar = MEM_callocN(sizeof(ARegion), "context region for buts");
73         BLI_addtail(&sbuts->regionbase, ar);
74         ar->regiontype = RGN_TYPE_CHANNELS;
75         ar->alignment = RGN_ALIGN_TOP;
76 #endif
77
78         /* main region */
79         ar = MEM_callocN(sizeof(ARegion), "main region for buts");
80         
81         BLI_addtail(&sbuts->regionbase, ar);
82         ar->regiontype = RGN_TYPE_WINDOW;
83
84         return (SpaceLink *)sbuts;
85 }
86
87 /* not spacelink itself */
88 static void buttons_free(SpaceLink *sl)
89 {       
90         SpaceButs *sbuts = (SpaceButs *) sl;
91
92         if (sbuts->path)
93                 MEM_freeN(sbuts->path);
94         
95         if (sbuts->texuser) {
96                 ButsContextTexture *ct = sbuts->texuser;
97                 BLI_freelistN(&ct->users);
98                 MEM_freeN(ct);
99         }
100 }
101
102 /* spacetype; init callback */
103 static void buttons_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
104 {
105         SpaceButs *sbuts = sa->spacedata.first;
106
107         /* auto-align based on size */
108         if (sbuts->align == BUT_AUTO || !sbuts->align) {
109                 if (sa->winx > sa->winy)
110                         sbuts->align = BUT_HORIZONTAL;
111                 else
112                         sbuts->align = BUT_VERTICAL;
113         }
114 }
115
116 static SpaceLink *buttons_duplicate(SpaceLink *sl)
117 {
118         SpaceButs *sbutsn = MEM_dupallocN(sl);
119         
120         /* clear or remove stuff from old */
121         sbutsn->path = NULL;
122         sbutsn->texuser = NULL;
123         
124         return (SpaceLink *)sbutsn;
125 }
126
127 /* add handlers, stuff you only do once or on area/region changes */
128 static void buttons_main_region_init(wmWindowManager *wm, ARegion *ar)
129 {
130         wmKeyMap *keymap;
131
132         ED_region_panels_init(wm, ar);
133
134         keymap = WM_keymap_find(wm->defaultconf, "Property Editor", SPACE_BUTS, 0);
135         WM_event_add_keymap_handler(&ar->handlers, keymap);
136 }
137
138 static void buttons_main_region_draw(const bContext *C, ARegion *ar)
139 {
140         /* draw entirely, view changes should be handled here */
141         SpaceButs *sbuts = CTX_wm_space_buts(C);
142         const bool vertical = (sbuts->align == BUT_VERTICAL);
143
144         buttons_context_compute(C, sbuts);
145
146         if (sbuts->mainb == BCONTEXT_SCENE)
147                 ED_region_panels(C, ar, "scene", sbuts->mainb, vertical);
148         else if (sbuts->mainb == BCONTEXT_RENDER)
149                 ED_region_panels(C, ar, "render", sbuts->mainb, vertical);
150         else if (sbuts->mainb == BCONTEXT_VIEW_LAYER)
151                 ED_region_panels(C, ar, "view_layer", sbuts->mainb, vertical);
152         else if (sbuts->mainb == BCONTEXT_WORLD)
153                 ED_region_panels(C, ar, "world", sbuts->mainb, vertical);
154         else if (sbuts->mainb == BCONTEXT_WORKSPACE)
155                 ED_region_panels(C, ar, "workspace", sbuts->mainb, vertical);
156         else if (sbuts->mainb == BCONTEXT_COLLECTION)
157                 ED_region_panels(C, ar, "collection", sbuts->mainb, vertical);
158         else if (sbuts->mainb == BCONTEXT_OBJECT)
159                 ED_region_panels(C, ar, "object", sbuts->mainb, vertical);
160         else if (sbuts->mainb == BCONTEXT_DATA)
161                 ED_region_panels(C, ar, "data", sbuts->mainb, vertical);
162         else if (sbuts->mainb == BCONTEXT_MATERIAL)
163                 ED_region_panels(C, ar, "material", sbuts->mainb, vertical);
164         else if (sbuts->mainb == BCONTEXT_TEXTURE)
165                 ED_region_panels(C, ar, "texture", sbuts->mainb, vertical);
166         else if (sbuts->mainb == BCONTEXT_PARTICLE)
167                 ED_region_panels(C, ar, "particle", sbuts->mainb, vertical);
168         else if (sbuts->mainb == BCONTEXT_PHYSICS)
169                 ED_region_panels(C, ar, "physics", sbuts->mainb, vertical);
170         else if (sbuts->mainb == BCONTEXT_BONE)
171                 ED_region_panels(C, ar, "bone", sbuts->mainb, vertical);
172         else if (sbuts->mainb == BCONTEXT_MODIFIER)
173                 ED_region_panels(C, ar, "modifier", sbuts->mainb, vertical);
174         else if (sbuts->mainb == BCONTEXT_CONSTRAINT)
175                 ED_region_panels(C, ar, "constraint", sbuts->mainb, vertical);
176         else if (sbuts->mainb == BCONTEXT_BONE_CONSTRAINT)
177                 ED_region_panels(C, ar, "bone_constraint", sbuts->mainb, vertical);
178
179         sbuts->re_align = 0;
180         sbuts->mainbo = sbuts->mainb;
181 }
182
183 static void buttons_main_region_listener(
184         bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn,
185         const Scene *UNUSED(scene))
186 {
187         /* context changes */
188         switch (wmn->category) {
189                 case NC_SCREEN:
190                         if (ELEM(wmn->data, ND_LAYER)) {
191                                 ED_region_tag_redraw(ar);
192                         }
193                         break;
194         }
195 }
196
197 static void buttons_operatortypes(void)
198 {
199         WM_operatortype_append(BUTTONS_OT_toolbox);
200         WM_operatortype_append(BUTTONS_OT_file_browse);
201         WM_operatortype_append(BUTTONS_OT_directory_browse);
202 }
203
204 static void buttons_keymap(struct wmKeyConfig *keyconf)
205 {
206         wmKeyMap *keymap = WM_keymap_find(keyconf, "Property Editor", SPACE_BUTS, 0);
207         
208         WM_keymap_add_item(keymap, "BUTTONS_OT_toolbox", RIGHTMOUSE, KM_PRESS, 0, 0);
209 }
210
211 /* add handlers, stuff you only do once or on area/region changes */
212 static void buttons_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
213 {
214         ED_region_header_init(ar);
215 }
216
217 static void buttons_header_region_draw(const bContext *C, ARegion *ar)
218 {
219         SpaceButs *sbuts = CTX_wm_space_buts(C);
220
221         /* Needed for RNA to get the good values! */
222         buttons_context_compute(C, sbuts);
223
224         ED_region_header(C, ar);
225 }
226
227 /* draw a certain button set only if properties area is currently
228  * showing that button set, to reduce unnecessary drawing. */
229 static void buttons_area_redraw(ScrArea *sa, short buttons)
230 {
231         SpaceButs *sbuts = sa->spacedata.first;
232         
233         /* if the area's current button set is equal to the one to redraw */
234         if (sbuts->mainb == buttons)
235                 ED_area_tag_redraw(sa);
236 }
237
238 /* reused! */
239 static void buttons_area_listener(
240         bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene),
241         WorkSpace *UNUSED(workspace))
242 {
243         SpaceButs *sbuts = sa->spacedata.first;
244
245         /* context changes */
246         switch (wmn->category) {
247                 case NC_SCENE:
248                         switch (wmn->data) {
249                                 case ND_RENDER_OPTIONS:
250                                         buttons_area_redraw(sa, BCONTEXT_RENDER);
251                                         buttons_area_redraw(sa, BCONTEXT_VIEW_LAYER);
252                                         break;
253                                 case ND_WORLD:
254                                         buttons_area_redraw(sa, BCONTEXT_WORLD);
255                                         sbuts->preview = 1;
256                                         break;
257                                 case ND_FRAME:
258                                         /* any buttons area can have animated properties so redraw all */
259                                         ED_area_tag_redraw(sa);
260                                         sbuts->preview = 1;
261                                         break;
262                                 case ND_OB_ACTIVE:
263                                         ED_area_tag_redraw(sa);
264                                         sbuts->preview = 1;
265                                         break;
266                                 case ND_KEYINGSET:
267                                         buttons_area_redraw(sa, BCONTEXT_SCENE);
268                                         break;
269                                 case ND_RENDER_RESULT:
270                                         break;
271                                 case ND_MODE:
272                                 case ND_LAYER:
273                                 default:
274                                         ED_area_tag_redraw(sa);
275                                         break;
276                         }
277                         break;
278                 case NC_OBJECT:
279                         switch (wmn->data) {
280                                 case ND_TRANSFORM:
281                                         buttons_area_redraw(sa, BCONTEXT_OBJECT);
282                                         buttons_area_redraw(sa, BCONTEXT_DATA); /* autotexpace flag */
283                                         break;
284                                 case ND_POSE:
285                                         buttons_area_redraw(sa, BCONTEXT_DATA);
286                                         break;
287                                 case ND_BONE_ACTIVE:
288                                 case ND_BONE_SELECT:
289                                         buttons_area_redraw(sa, BCONTEXT_BONE);
290                                         buttons_area_redraw(sa, BCONTEXT_BONE_CONSTRAINT);
291                                         buttons_area_redraw(sa, BCONTEXT_DATA);
292                                         break;
293                                 case ND_MODIFIER:
294                                         if (wmn->action == NA_RENAME)
295                                                 ED_area_tag_redraw(sa);
296                                         else
297                                                 buttons_area_redraw(sa, BCONTEXT_MODIFIER);
298                                         buttons_area_redraw(sa, BCONTEXT_PHYSICS);
299                                         break;
300                                 case ND_CONSTRAINT:
301                                         buttons_area_redraw(sa, BCONTEXT_CONSTRAINT);
302                                         buttons_area_redraw(sa, BCONTEXT_BONE_CONSTRAINT);
303                                         break;
304                                 case ND_PARTICLE:
305                                         if (wmn->action == NA_EDITED)
306                                                 buttons_area_redraw(sa, BCONTEXT_PARTICLE);
307                                         sbuts->preview = 1;
308                                         break;
309                                 case ND_DRAW:
310                                         buttons_area_redraw(sa, BCONTEXT_OBJECT);
311                                         buttons_area_redraw(sa, BCONTEXT_DATA);
312                                         buttons_area_redraw(sa, BCONTEXT_PHYSICS);
313                                         break;
314                                 case ND_SHADING:
315                                 case ND_SHADING_DRAW:
316                                 case ND_SHADING_LINKS:
317                                 case ND_SHADING_PREVIEW:
318                                         /* currently works by redraws... if preview is set, it (re)starts job */
319                                         sbuts->preview = 1;
320                                         break;
321                                 default:
322                                         /* Not all object RNA props have a ND_ notifier (yet) */
323                                         ED_area_tag_redraw(sa);
324                                         break;
325                         }
326                         break;
327                 case NC_GEOM:
328                         switch (wmn->data) {
329                                 case ND_SELECT:
330                                 case ND_DATA:
331                                 case ND_VERTEX_GROUP:
332                                         ED_area_tag_redraw(sa);
333                                         break;
334                         }
335                         break;
336                 case NC_MATERIAL:
337                         ED_area_tag_redraw(sa);
338                         switch (wmn->data) {
339                                 case ND_SHADING:
340                                 case ND_SHADING_DRAW:
341                                 case ND_SHADING_LINKS:
342                                 case ND_SHADING_PREVIEW:
343                                 case ND_NODES:
344                                         /* currently works by redraws... if preview is set, it (re)starts job */
345                                         sbuts->preview = 1;
346                                         break;
347                         }
348                         break;
349                 case NC_WORLD:
350                         buttons_area_redraw(sa, BCONTEXT_WORLD);
351                         sbuts->preview = 1;
352                         break;
353                 case NC_LAMP:
354                         buttons_area_redraw(sa, BCONTEXT_DATA);
355                         sbuts->preview = 1;
356                         break;
357                 case NC_GROUP:
358                         buttons_area_redraw(sa, BCONTEXT_OBJECT);
359                         break;
360                 case NC_BRUSH:
361                         buttons_area_redraw(sa, BCONTEXT_TEXTURE);
362                         sbuts->preview = 1;
363                         break;
364                 case NC_TEXTURE:
365                 case NC_IMAGE:
366                         if (wmn->action != NA_PAINTING) {
367                                 ED_area_tag_redraw(sa);
368                                 sbuts->preview = 1;
369                         }
370                         break;
371                 case NC_SPACE:
372                         if (wmn->data == ND_SPACE_PROPERTIES)
373                                 ED_area_tag_redraw(sa);
374                         break;
375                 case NC_ID:
376                         if (wmn->action == NA_RENAME)
377                                 ED_area_tag_redraw(sa);
378                         break;
379                 case NC_ANIMATION:
380                         switch (wmn->data) {
381                                 case ND_KEYFRAME:
382                                         if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED))
383                                                 ED_area_tag_redraw(sa);
384                                         break;
385                         }
386                         break;
387                 case NC_NODE:
388                         if (wmn->action == NA_SELECTED) {
389                                 ED_area_tag_redraw(sa);
390                                 /* new active node, update texture preview */
391                                 if (sbuts->mainb == BCONTEXT_TEXTURE)
392                                         sbuts->preview = 1;
393                         }
394                         break;
395                 /* Listener for preview render, when doing an global undo. */
396                 case NC_WM:
397                         if (wmn->data == ND_UNDO) {
398                                 ED_area_tag_redraw(sa);
399                                 sbuts->preview = 1;
400                         }
401                         break;
402 #ifdef WITH_FREESTYLE
403                 case NC_LINESTYLE:
404                         ED_area_tag_redraw(sa);
405                         sbuts->preview = 1;
406                         break;
407 #endif
408         }
409
410         if (wmn->data == ND_KEYS)
411                 ED_area_tag_redraw(sa);
412 }
413
414 static void buttons_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
415 {
416         SpaceButs *sbuts = (SpaceButs *)slink;
417
418         if (sbuts->pinid == old_id) {
419                 sbuts->pinid = new_id;
420                 if (new_id == NULL) {
421                         sbuts->flag &= ~SB_PIN_CONTEXT;
422                 }
423         }
424
425         if (sbuts->path) {
426                 ButsContextPath *path = sbuts->path;
427                 int i;
428
429                 for (i = 0; i < path->len; i++) {
430                         if (path->ptr[i].id.data == old_id) {
431                                 break;
432                         }
433                 }
434
435                 if (i == path->len) {
436                         /* pass */
437                 }
438                 else if (new_id == NULL) {
439                         if (i == 0) {
440                                 MEM_SAFE_FREE(sbuts->path);
441                         }
442                         else {
443                                 memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
444                                 path->len = i;
445                         }
446                 }
447                 else {
448                         RNA_id_pointer_create(new_id, &path->ptr[i]);
449                         /* There is no easy way to check/make path downwards valid, just nullify it.
450                          * Next redraw will rebuild this anyway. */
451                         i++;
452                         memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
453                         path->len = i;
454                 }
455         }
456
457         if (sbuts->texuser) {
458                 ButsContextTexture *ct = sbuts->texuser;
459                 if ((ID *)ct->texture == old_id) {
460                         ct->texture = (Tex *)new_id;
461                 }
462                 BLI_freelistN(&ct->users);
463                 ct->user = NULL;
464         }
465 }
466
467 /* only called once, from space/spacetypes.c */
468 void ED_spacetype_buttons(void)
469 {
470         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype buttons");
471         ARegionType *art;
472         
473         st->spaceid = SPACE_BUTS;
474         strncpy(st->name, "Buttons", BKE_ST_MAXNAME);
475         
476         st->new = buttons_new;
477         st->free = buttons_free;
478         st->init = buttons_init;
479         st->duplicate = buttons_duplicate;
480         st->operatortypes = buttons_operatortypes;
481         st->keymap = buttons_keymap;
482         st->listener = buttons_area_listener;
483         st->context = buttons_context;
484         st->id_remap = buttons_id_remap;
485
486         /* regions: main window */
487         art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
488         art->regionid = RGN_TYPE_WINDOW;
489         art->init = buttons_main_region_init;
490         art->draw = buttons_main_region_draw;
491         art->listener = buttons_main_region_listener;
492         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
493         BLI_addhead(&st->regiontypes, art);
494
495         buttons_context_register(art);
496         
497         /* regions: header */
498         art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
499         art->regionid = RGN_TYPE_HEADER;
500         art->prefsizey = HEADERY;
501         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
502         
503         art->init = buttons_header_region_init;
504         art->draw = buttons_header_region_draw;
505         BLI_addhead(&st->regiontypes, art);
506
507         BKE_spacetype_register(st);
508 }
509