746497f0ff5e2e8f804495b64b5b4f40fa3f9216
[blender-staging.git] / source / blender / editors / gpencil / gpencil_data.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, Joshua Leung
19  * This is a new part of Blender
20  *
21  * Contributor(s): Joshua Leung
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  *
25  * Operators for dealing with GP datablocks and layers
26  */
27
28 /** \file blender/editors/gpencil/gpencil_data.c
29  *  \ingroup edgpencil
30  */
31
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <stddef.h>
37 #include <math.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_utildefines.h"
43
44 #include "BLT_translation.h"
45
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_space_types.h"
49 #include "DNA_view3d_types.h"
50 #include "DNA_gpencil_types.h"
51
52 #include "BKE_context.h"
53 #include "BKE_global.h"
54 #include "BKE_gpencil.h"
55 #include "BKE_library.h"
56 #include "BKE_object.h"
57 #include "BKE_report.h"
58 #include "BKE_scene.h"
59 #include "BKE_screen.h"
60
61 #include "UI_interface.h"
62 #include "UI_resources.h"
63
64 #include "WM_api.h"
65 #include "WM_types.h"
66
67 #include "RNA_access.h"
68 #include "RNA_define.h"
69 #include "RNA_enum_types.h"
70
71 #include "ED_gpencil.h"
72
73 #include "gpencil_intern.h"
74
75
76 /* ************************************************ */
77 /* Datablock Operators */
78
79 /* ******************* Add New Data ************************ */
80
81 /* add new datablock - wrapper around API */
82 static int gp_data_add_exec(bContext *C, wmOperator *op)
83 {
84         bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
85         
86         if (gpd_ptr == NULL) {
87                 BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
88                 return OPERATOR_CANCELLED;
89         }
90         else {
91                 /* decrement user count and add new datablock */
92                 bGPdata *gpd = (*gpd_ptr);
93                 
94                 id_us_min(&gpd->id);
95                 *gpd_ptr = gpencil_data_addnew(DATA_("GPencil"));
96         }
97         
98         /* notifiers */
99         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
100         
101         return OPERATOR_FINISHED;
102 }
103
104 void GPENCIL_OT_data_add(wmOperatorType *ot)
105 {
106         /* identifiers */
107         ot->name = "Grease Pencil Add New";
108         ot->idname = "GPENCIL_OT_data_add";
109         ot->description = "Add new Grease Pencil datablock";
110         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
111         
112         /* callbacks */
113         ot->exec = gp_data_add_exec;
114         ot->poll = gp_add_poll;
115 }
116
117 /* ******************* Unlink Data ************************ */
118
119 /* poll callback for adding data/layers - special */
120 static int gp_data_unlink_poll(bContext *C)
121 {
122         bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
123         
124         /* if we have access to some active data, make sure there's a datablock before enabling this */
125         return (gpd_ptr && *gpd_ptr);
126 }
127
128
129 /* unlink datablock - wrapper around API */
130 static int gp_data_unlink_exec(bContext *C, wmOperator *op)
131 {
132         bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
133         
134         if (gpd_ptr == NULL) {
135                 BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
136                 return OPERATOR_CANCELLED;
137         }
138         else {
139                 /* just unlink datablock now, decreasing its user count */
140                 bGPdata *gpd = (*gpd_ptr);
141
142                 id_us_min(&gpd->id);
143                 *gpd_ptr = NULL;
144         }
145         
146         /* notifiers */
147         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
148         
149         return OPERATOR_FINISHED;
150 }
151
152 void GPENCIL_OT_data_unlink(wmOperatorType *ot)
153 {
154         /* identifiers */
155         ot->name = "Grease Pencil Unlink";
156         ot->idname = "GPENCIL_OT_data_unlink";
157         ot->description = "Unlink active Grease Pencil datablock";
158         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
159         
160         /* callbacks */
161         ot->exec = gp_data_unlink_exec;
162         ot->poll = gp_data_unlink_poll;
163 }
164
165
166 /* ************************************************ */
167 /* Layer Operators */
168
169 /* ******************* Add New Layer ************************ */
170
171 /* add new layer - wrapper around API */
172 static int gp_layer_add_exec(bContext *C, wmOperator *op)
173 {
174         bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
175         
176         /* if there's no existing Grease-Pencil data there, add some */
177         if (gpd_ptr == NULL) {
178                 BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
179                 return OPERATOR_CANCELLED;
180         }
181         if (*gpd_ptr == NULL)
182                 *gpd_ptr = gpencil_data_addnew(DATA_("GPencil"));
183         
184         /* add new layer now */
185         gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true);
186         
187         /* notifiers */
188         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
189         
190         return OPERATOR_FINISHED;
191 }
192
193 void GPENCIL_OT_layer_add(wmOperatorType *ot)
194 {
195         /* identifiers */
196         ot->name = "Add New Layer";
197         ot->idname = "GPENCIL_OT_layer_add";
198         ot->description = "Add new Grease Pencil layer for the active Grease Pencil datablock";
199         
200         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
201         
202         /* callbacks */
203         ot->exec = gp_layer_add_exec;
204         ot->poll = gp_add_poll;
205 }
206
207 /* ******************* Remove Active Layer ************************* */
208
209 static int gp_layer_remove_exec(bContext *C, wmOperator *op)
210 {
211         bGPdata *gpd = ED_gpencil_data_get_active(C);
212         bGPDlayer *gpl = gpencil_layer_getactive(gpd);
213         
214         /* sanity checks */
215         if (ELEM(NULL, gpd, gpl))
216                 return OPERATOR_CANCELLED;
217         
218         if (gpl->flag & GP_LAYER_LOCKED) {
219                 BKE_report(op->reports, RPT_ERROR, "Cannot delete locked layers");
220                 return OPERATOR_CANCELLED;
221         }
222         
223         /* make the layer before this the new active layer
224          * - use the one after if this is the first
225          * - if this is the only layer, this naturally becomes NULL
226          */
227         if (gpl->prev)
228                 gpencil_layer_setactive(gpd, gpl->prev);
229         else
230                 gpencil_layer_setactive(gpd, gpl->next);
231         
232         /* delete the layer now... */
233         gpencil_layer_delete(gpd, gpl);
234         
235         /* notifiers */
236         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
237         
238         return OPERATOR_FINISHED;
239 }
240
241 void GPENCIL_OT_layer_remove(wmOperatorType *ot)
242 {
243         /* identifiers */
244         ot->name = "Remove Layer";
245         ot->idname = "GPENCIL_OT_layer_remove";
246         ot->description = "Remove active Grease Pencil layer";
247         
248         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
249         
250         /* callbacks */
251         ot->exec = gp_layer_remove_exec;
252         ot->poll = gp_active_layer_poll;
253 }
254
255 /* ******************* Move Layer Up/Down ************************** */
256
257 enum {
258         GP_LAYER_MOVE_UP   = -1,
259         GP_LAYER_MOVE_DOWN = 1
260 };
261
262 static int gp_layer_move_exec(bContext *C, wmOperator *op)
263 {
264         bGPdata *gpd = ED_gpencil_data_get_active(C);
265         bGPDlayer *gpl = gpencil_layer_getactive(gpd);
266         
267         int direction = RNA_enum_get(op->ptr, "type");
268         
269         /* sanity checks */
270         if (ELEM(NULL, gpd, gpl))
271                 return OPERATOR_CANCELLED;
272         
273         /* up or down? */
274         if (direction == GP_LAYER_MOVE_UP) {
275                 /* up */
276                 BLI_remlink(&gpd->layers, gpl);
277                 BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl);
278         }
279         else {
280                 /* down */
281                 BLI_remlink(&gpd->layers, gpl);
282                 BLI_insertlinkafter(&gpd->layers, gpl->next, gpl);
283         }
284         
285         /* notifiers */
286         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
287         
288         return OPERATOR_FINISHED;
289 }
290
291 void GPENCIL_OT_layer_move(wmOperatorType *ot)
292 {
293         static EnumPropertyItem slot_move[] = {
294                 {GP_LAYER_MOVE_UP, "UP", 0, "Up", ""},
295                 {GP_LAYER_MOVE_DOWN, "DOWN", 0, "Down", ""},
296                 {0, NULL, 0, NULL, NULL}
297         };
298         
299         /* identifiers */
300         ot->name = "Move Grease Pencil Layer";
301         ot->idname = "GPENCIL_OT_layer_move";
302         ot->description = "Move the active Grease Pencil layer up/down in the list";
303         
304         /* api callbacks */
305         ot->exec = gp_layer_move_exec;
306         ot->poll = gp_active_layer_poll;
307         
308         /* flags */
309         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
310         
311         ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
312 }
313
314 /* ********************* Duplicate Layer ************************** */
315
316 static int gp_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
317 {
318         bGPdata *gpd = ED_gpencil_data_get_active(C);
319         bGPDlayer *gpl = gpencil_layer_getactive(gpd);
320         bGPDlayer *new_layer;
321         
322         /* sanity checks */
323         if (ELEM(NULL, gpd, gpl))
324                 return OPERATOR_CANCELLED;
325         
326         /* make copy of layer, and add it immediately after the existing layer */
327         new_layer = gpencil_layer_duplicate(gpl);
328         BLI_insertlinkafter(&gpd->layers, gpl, new_layer);
329         
330         /* ensure new layer has a unique name, and is now the active layer */
331         BLI_uniquename(&gpd->layers, new_layer, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(new_layer->info));
332         gpencil_layer_setactive(gpd, new_layer);
333         
334         /* notifiers */
335         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
336         
337         return OPERATOR_FINISHED;
338 }
339
340 void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
341 {
342         /* identifiers */
343         ot->name = "Duplicate Layer";
344         ot->idname = "GPENCIL_OT_layer_duplicate";
345         ot->description = "Make a copy of the active Grease Pencil layer";
346         
347         /* callbacks */
348         ot->exec = gp_layer_copy_exec;
349         ot->poll = gp_active_layer_poll;
350         
351         /* flags */
352         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
353 }
354
355 /* *********************** Hide Layers ******************************** */
356
357 static int gp_hide_exec(bContext *C, wmOperator *op)
358 {
359         bGPdata *gpd = ED_gpencil_data_get_active(C);
360         bGPDlayer *layer = gpencil_layer_getactive(gpd);
361         bool unselected = RNA_boolean_get(op->ptr, "unselected");
362         
363         /* sanity checks */
364         if (ELEM(NULL, gpd, layer))
365                 return OPERATOR_CANCELLED;
366         
367         if (unselected) {
368                 bGPDlayer *gpl;
369                 
370                 /* hide unselected */
371                 for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
372                         if (gpl != layer) {
373                                 gpl->flag |= GP_LAYER_HIDE;
374                         }
375                 }
376         }
377         else {
378                 /* hide selected/active */
379                 layer->flag |= GP_LAYER_HIDE;
380         }
381         
382         /* notifiers */
383         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
384         
385         return OPERATOR_FINISHED;
386 }
387
388 void GPENCIL_OT_hide(wmOperatorType *ot)
389 {
390         /* identifiers */
391         ot->name = "Hide Layer(s)";
392         ot->idname = "GPENCIL_OT_hide";
393         ot->description = "Hide selected/unselected Grease Pencil layers";
394         
395         /* callbacks */
396         ot->exec = gp_hide_exec;
397         ot->poll = gp_active_layer_poll; /* NOTE: we need an active layer to play with */
398         
399         /* flags */
400         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
401         
402         /* props */
403         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers");
404 }
405
406 /* ********************** Show All Layers ***************************** */
407
408 /* poll callback for showing layers */
409 static int gp_reveal_poll(bContext *C)
410 {
411         return ED_gpencil_data_get_active(C) != NULL;
412 }
413
414 static int gp_reveal_exec(bContext *C, wmOperator *UNUSED(op))
415 {
416         bGPdata *gpd = ED_gpencil_data_get_active(C);
417         bGPDlayer *gpl;
418         
419         /* sanity checks */
420         if (gpd == NULL)
421                 return OPERATOR_CANCELLED;
422         
423         /* make all layers visible */
424         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
425                 gpl->flag &= ~GP_LAYER_HIDE;
426         }
427         
428         /* notifiers */
429         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
430         
431         return OPERATOR_FINISHED;
432 }
433
434 void GPENCIL_OT_reveal(wmOperatorType *ot)
435 {
436         /* identifiers */
437         ot->name = "Show All Layers";
438         ot->idname = "GPENCIL_OT_reveal";
439         ot->description = "Show all Grease Pencil layers";
440         
441         /* callbacks */
442         ot->exec = gp_reveal_exec;
443         ot->poll = gp_reveal_poll;
444         
445         /* flags */
446         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
447 }
448
449 /* ***************** Lock/Unlock All Layers ************************ */
450
451 static int gp_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
452 {
453         bGPdata *gpd = ED_gpencil_data_get_active(C);
454         bGPDlayer *gpl;
455         
456         /* sanity checks */
457         if (gpd == NULL)
458                 return OPERATOR_CANCELLED;
459         
460         /* make all layers non-editable */
461         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
462                 gpl->flag |= GP_LAYER_LOCKED;
463         }
464         
465         /* notifiers */
466         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
467         
468         return OPERATOR_FINISHED;
469 }
470
471 void GPENCIL_OT_lock_all(wmOperatorType *ot)
472 {
473         /* identifiers */
474         ot->name = "Lock All Layers";
475         ot->idname = "GPENCIL_OT_lock_all";
476         ot->description = "Lock all Grease Pencil layers to prevent them from being accidentally modified";
477         
478         /* callbacks */
479         ot->exec = gp_lock_all_exec;
480         ot->poll = gp_reveal_poll; /* XXX: could use dedicated poll later */
481         
482         /* flags */
483         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
484 }
485
486 /* -------------------------- */
487
488 static int gp_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
489 {
490         bGPdata *gpd = ED_gpencil_data_get_active(C);
491         bGPDlayer *gpl;
492         
493         /* sanity checks */
494         if (gpd == NULL)
495                 return OPERATOR_CANCELLED;
496         
497         /* make all layers editable again */
498         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
499                 gpl->flag &= ~GP_LAYER_LOCKED;
500         }
501         
502         /* notifiers */
503         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
504         
505         return OPERATOR_FINISHED;
506 }
507
508 void GPENCIL_OT_unlock_all(wmOperatorType *ot)
509 {
510         /* identifiers */
511         ot->name = "Unlock All Layers";
512         ot->idname = "GPENCIL_OT_unlock_all";
513         ot->description = "Unlock all Grease Pencil layers so that they can be edited";
514         
515         /* callbacks */
516         ot->exec = gp_unlock_all_exec;
517         ot->poll = gp_reveal_poll; /* XXX: could use dedicated poll later */
518         
519         /* flags */
520         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
521 }
522
523 /* ********************** Isolate Layer **************************** */
524
525 static int gp_isolate_layer_exec(bContext *C, wmOperator *op)
526 {
527         bGPdata *gpd = ED_gpencil_data_get_active(C);
528         bGPDlayer *layer = gpencil_layer_getactive(gpd);
529         bGPDlayer *gpl;
530         int flags = GP_LAYER_LOCKED;
531         bool isolate = false;
532         
533         if (RNA_boolean_get(op->ptr, "affect_visibility"))
534                 flags |= GP_LAYER_HIDE;
535                 
536         if (ELEM(NULL, gpd, layer)) {
537                 BKE_report(op->reports, RPT_ERROR, "No active layer to isolate");
538                 return OPERATOR_CANCELLED;
539         }
540         
541         /* Test whether to isolate or clear all flags */
542         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
543                 /* Skip if this is the active layer */
544                 if (gpl == layer)
545                         continue;
546                 
547                 /* If the flags aren't set, that means that the layer is
548                  * not alone, so we have some layers to isolate still
549                  */
550                 if ((gpl->flag & flags) == 0) {
551                         isolate = true;
552                         break;
553                 }
554         }
555         
556         /* Set/Clear flags as appropriate */
557         /* TODO: Include onionskinning on this list? */
558         if (isolate) {
559                 /* Set flags on all "other" layers */
560                 for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
561                         if (gpl == layer)
562                                 continue;
563                         else
564                                 gpl->flag |= flags;
565                 }
566         }
567         else {
568                 /* Clear flags - Restore everything else */
569                 for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
570                         gpl->flag &= ~flags;
571                 }
572         }
573         
574         /* notifiers */
575         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
576         
577         return OPERATOR_FINISHED;
578 }
579
580 void GPENCIL_OT_layer_isolate(wmOperatorType *ot)
581 {
582         /* identifiers */
583         ot->name = "Isolate Layer";
584         ot->idname = "GPENCIL_OT_layer_isolate";
585         ot->description = "Toggle whether the active layer is the only one that can be edited and/or visible";
586         
587         /* callbacks */
588         ot->exec = gp_isolate_layer_exec;
589         ot->poll = gp_active_layer_poll;
590         
591         /* flags */
592         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
593         
594         /* properties */
595         RNA_def_boolean(ot->srna, "affect_visibility", false, "Affect Visibility",
596                         "In addition to toggling the editability, also affect the visibility");
597 }
598
599 /* ********************** Change Layer ***************************** */
600
601 static int gp_layer_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
602 {
603         uiPopupMenu *pup;
604         uiLayout *layout;
605         
606         /* call the menu, which will call this operator again, hence the canceled */
607         pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
608         layout = UI_popup_menu_layout(pup);
609         uiItemsEnumO(layout, "GPENCIL_OT_layer_change", "layer");
610         UI_popup_menu_end(C, pup);
611         
612         return OPERATOR_INTERFACE;
613 }
614
615 static int gp_layer_change_exec(bContext *C, wmOperator *op)
616 {
617         bGPdata *gpd = CTX_data_gpencil_data(C);
618         bGPDlayer *gpl = NULL;
619         int layer_num = RNA_enum_get(op->ptr, "layer");
620         
621         /* Get layer or create new one */
622         if (layer_num == -1) {
623                 /* Create layer */
624                 gpl = gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
625         }
626         else {
627                 /* Try to get layer */
628                 gpl = BLI_findlink(&gpd->layers, layer_num);
629                 
630                 if (gpl == NULL) {
631                         BKE_reportf(op->reports, RPT_ERROR, "Cannot change to non-existent layer (index = %d)", layer_num);
632                         return OPERATOR_CANCELLED;
633                 }
634         }
635         
636         /* Set active layer */
637         gpencil_layer_setactive(gpd, gpl);
638         
639         /* updates */
640         WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
641         
642         return OPERATOR_FINISHED;
643 }
644
645 void GPENCIL_OT_layer_change(wmOperatorType *ot)
646 {
647         /* identifiers */
648         ot->name = "Change Layer";
649         ot->idname = "GPENCIL_OT_layer_change";
650         ot->description = "Change active Grease Pencil layer";
651         
652         /* callbacks */
653         ot->invoke = gp_layer_change_invoke;
654         ot->exec = gp_layer_change_exec;
655         ot->poll = gp_active_layer_poll;
656         
657         /* flags */
658         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
659         
660         /* gp layer to use (dynamic enum) */
661         ot->prop = RNA_def_enum(ot->srna, "layer", DummyRNA_DEFAULT_items, 0, "Grease Pencil Layer", "");
662         RNA_def_enum_funcs(ot->prop, ED_gpencil_layers_with_new_enum_itemf);
663 }
664
665 /* ************************************************ */