Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / manipulators / intern / wm_manipulator_type.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/windowmanager/manipulators/intern/wm_manipulator_type.c
22  *  \ingroup wm
23  */
24
25 #include "BKE_context.h"
26
27 #include "BLI_ghash.h"
28 #include "BLI_string.h"
29 #include "BLI_string_utils.h"
30
31 #include "MEM_guardedalloc.h"
32
33 #include "RNA_access.h"
34 #include "RNA_define.h"
35
36 #include "WM_api.h"
37 #include "WM_types.h"
38
39 /* only for own init/exit calls (wm_manipulatortype_init/wm_manipulatortype_free) */
40 #include "wm.h"
41
42 /* own includes */
43 #include "wm_manipulator_wmapi.h"
44 #include "wm_manipulator_intern.h"
45
46
47 /** \name Manipulator Type Append
48  *
49  * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends.
50  * \{ */
51
52 static GHash *global_manipulatortype_hash = NULL;
53
54 const wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet)
55 {
56         if (idname[0]) {
57                 wmManipulatorType *wt;
58
59                 wt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
60                 if (wt) {
61                         return wt;
62                 }
63
64                 if (!quiet) {
65                         printf("search for unknown manipulator '%s'\n", idname);
66                 }
67         }
68         else {
69                 if (!quiet) {
70                         printf("search for empty manipulator\n");
71                 }
72         }
73
74         return NULL;
75 }
76
77 /* caller must free */
78 void WM_manipulatortype_iter(GHashIterator *ghi)
79 {
80         BLI_ghashIterator_init(ghi, global_manipulatortype_hash);
81 }
82
83 static wmManipulatorType *wm_manipulatortype_append__begin(void)
84 {
85         wmManipulatorType *wt = MEM_callocN(sizeof(wmManipulatorType), "manipulatortype");
86         wt->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_ManipulatorProperties);
87 #if 0
88         /* Set the default i18n context now, so that opfunc can redefine it if needed! */
89         RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
90         ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
91 #endif
92         return wt;
93 }
94 static void wm_manipulatortype_append__end(wmManipulatorType *wt)
95 {
96         BLI_assert(wt->struct_size >= sizeof(wmManipulator));
97
98         RNA_def_struct_identifier(wt->srna, wt->idname);
99
100         BLI_ghash_insert(global_manipulatortype_hash, (void *)wt->idname, wt);
101 }
102
103 void WM_manipulatortype_append(void (*wtfunc)(struct wmManipulatorType *))
104 {
105         wmManipulatorType *wt = wm_manipulatortype_append__begin();
106         wtfunc(wt);
107         wm_manipulatortype_append__end(wt);
108 }
109
110 void WM_manipulatortype_append_ptr(void (*wtfunc)(struct wmManipulatorType *, void *), void *userdata)
111 {
112         wmManipulatorType *mt = wm_manipulatortype_append__begin();
113         wtfunc(mt, userdata);
114         wm_manipulatortype_append__end(mt);
115 }
116
117 /**
118  * Free but don't remove from ghash.
119  */
120 static void manipulatortype_free(wmManipulatorType *wt)
121 {
122         BLI_freelistN(&wt->target_property_defs);
123         MEM_freeN(wt);
124 }
125
126 void WM_manipulatortype_remove_ptr(wmManipulatorType *wt)
127 {
128         BLI_assert(wt == WM_manipulatortype_find(wt->idname, false));
129
130         BLI_ghash_remove(global_manipulatortype_hash, wt->idname, NULL, NULL);
131
132         manipulatortype_free(wt);
133 }
134
135 bool WM_manipulatortype_remove(const char *idname)
136 {
137         wmManipulatorType *wt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
138
139         if (wt == NULL) {
140                 return false;
141         }
142
143         WM_manipulatortype_remove_ptr(wt);
144
145         return true;
146 }
147
148 static void wm_manipulatortype_ghash_free_cb(wmManipulatorType *mt)
149 {
150         manipulatortype_free(mt);
151 }
152
153 void wm_manipulatortype_free(void)
154 {
155         BLI_ghash_free(global_manipulatortype_hash, NULL, (GHashValFreeFP)wm_manipulatortype_ghash_free_cb);
156         global_manipulatortype_hash = NULL;
157 }
158
159 /* called on initialize WM_init() */
160 void wm_manipulatortype_init(void)
161 {
162         /* reserve size is set based on blender default setup */
163         global_manipulatortype_hash = BLI_ghash_str_new_ex("wm_manipulatortype_init gh", 128);
164 }
165
166 /** \} */