Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / blender_user_menu.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  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/blenkernel/intern/blender_user_menu.c
22  *  \ingroup bke
23  *
24  * User defined menu API.
25  */
26
27 #include <string.h>
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_listbase.h"
32 #include "BLI_string.h"
33
34 #include "DNA_userdef_types.h"
35
36 #include "BKE_blender_user_menu.h"
37 #include "BKE_idprop.h"
38
39 /* -------------------------------------------------------------------- */
40 /** \name Menu Type
41  * \{ */
42
43 bUserMenu *BKE_blender_user_menu_find(
44         ListBase *lb, char space_type, const char *context)
45 {
46         for (bUserMenu *um = lb->first; um; um = um->next) {
47                 if ((space_type == um->space_type) &&
48                     (STREQ(context, um->context)))
49                 {
50                         return um;
51                 }
52         }
53         return NULL;
54 }
55
56 bUserMenu *BKE_blender_user_menu_ensure(
57         ListBase *lb, char space_type, const char *context)
58 {
59         bUserMenu *um = BKE_blender_user_menu_find(lb, space_type, context);
60         if (um == NULL) {
61                 um = MEM_callocN(sizeof(bUserMenu), __func__);
62                 um->space_type = space_type;
63                 STRNCPY(um->context, context);
64                 BLI_addhead(lb, um);
65         }
66         return um;
67 }
68
69 /** \} */
70
71 /* -------------------------------------------------------------------- */
72 /** \name Menu Item
73  * \{ */
74
75 bUserMenuItem *BKE_blender_user_menu_item_add(ListBase *lb, int type)
76 {
77         uint size;
78
79         if (type == USER_MENU_TYPE_SEP) {
80                 size = sizeof(bUserMenuItem);
81         }
82         else if (type == USER_MENU_TYPE_OPERATOR) {
83                 size = sizeof(bUserMenuItem_Op);
84         }
85         else if (type == USER_MENU_TYPE_MENU) {
86                 size = sizeof(bUserMenuItem_Menu);
87         }
88         else if (type == USER_MENU_TYPE_PROP) {
89                 size = sizeof(bUserMenuItem_Prop);
90         }
91         else {
92                 size = sizeof(bUserMenuItem);
93                 BLI_assert(0);
94         }
95
96         bUserMenuItem *umi = MEM_callocN(size, __func__);
97         umi->type = type;
98         BLI_addtail(lb, umi);
99         return umi;
100 }
101
102 void BKE_blender_user_menu_item_free(bUserMenuItem *umi)
103 {
104         if (umi->type == USER_MENU_TYPE_OPERATOR) {
105                 bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
106                 if (umi_op->prop) {
107                         IDP_FreeProperty(umi_op->prop);
108                         MEM_freeN(umi_op->prop);
109                 }
110         }
111         MEM_freeN(umi);
112 }
113
114 void BKE_blender_user_menu_item_free_list(ListBase *lb)
115 {
116         for (bUserMenuItem *umi = lb->first, *umi_next; umi; umi = umi_next) {
117                 umi_next = umi->next;
118                 BKE_blender_user_menu_item_free(umi);
119         }
120         BLI_listbase_clear(lb);
121 }