Blender V4.5
buttons_texture.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_listbase.h"
15#include "BLI_string.h"
16#include "BLI_utildefines.h"
17
18#include "BLT_translation.hh"
19
20#include "DNA_ID.h"
21#include "DNA_brush_types.h"
22#include "DNA_linestyle_types.h"
23#include "DNA_modifier_types.h"
24#include "DNA_node_types.h"
26#include "DNA_object_types.h"
27#include "DNA_particle_types.h"
28#include "DNA_scene_types.h"
29#include "DNA_screen_types.h"
30#include "DNA_space_types.h"
32
33#include "BKE_context.hh"
34#include "BKE_layer.hh"
35#include "BKE_lib_id.hh"
36#include "BKE_linestyle.h"
37#include "BKE_modifier.hh"
39#include "BKE_node_runtime.hh"
40#include "BKE_paint.hh"
41#include "BKE_particle.h"
42
43#include "RNA_access.hh"
44#include "RNA_prototypes.hh"
45
46#include "UI_interface.hh"
47#include "UI_resources.hh"
48
49#include "ED_node.hh"
50#include "ED_screen.hh"
51
52#include "WM_api.hh"
53#include "WM_types.hh"
54
56
57#include "buttons_intern.hh" /* own include */
58
61
62/************************* Texture User **************************/
63
65 ID *id,
67 PropertyRNA *prop,
68 bNodeTree *ntree,
69 bNode *node,
70 bNodeSocket *socket,
71 const char *category,
72 int icon,
73 const char *name)
74{
75 ButsTextureUser *user = MEM_new<ButsTextureUser>("ButsTextureUser");
76
77 user->id = id;
78 user->ptr = ptr;
79 user->prop = prop;
80 user->ntree = ntree;
81 user->node = node;
82 user->socket = socket;
83 user->category = category;
84 user->icon = icon;
85 user->name = name;
87
88 BLI_addtail(users, user);
89}
90
92 ID *id,
94 PropertyRNA *prop,
95 const char *category,
96 int icon,
97 const char *name)
98{
99 ButsTextureUser *user = MEM_new<ButsTextureUser>("ButsTextureUser");
100
101 user->id = id;
102 user->ptr = ptr;
103 user->prop = prop;
104 user->category = category;
105 user->icon = icon;
106 user->name = name;
108
109 BLI_addtail(users, user);
110}
111
113 ID *id,
114 bNodeTree *ntree,
115 bNode *node,
117 PropertyRNA *prop,
118 const char *category,
119 int icon,
120 const char *name)
121{
122 ButsTextureUser *user = MEM_new<ButsTextureUser>("ButsTextureUser");
123
124 user->id = id;
125 user->ntree = ntree;
126 user->node = node;
127 user->ptr = ptr;
128 user->prop = prop;
129 user->category = category;
130 user->icon = icon;
131 user->name = name;
133
134 BLI_addtail(users, user);
135}
136
138 ID *id,
139 MTex *mtex,
140 const char *category)
141{
142 PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_TextureSlot, mtex);
143 PropertyRNA *prop = RNA_struct_find_property(&ptr, "texture");
144
146 users, id, ptr, prop, category, RNA_struct_ui_icon(ptr.type), BKE_id_name(mtex->tex->id));
147}
148
150 ID *id,
151 bNodeTree *ntree,
152 const char *category)
153{
154 if (ntree) {
155 for (bNode *node : ntree->all_nodes()) {
156 if (node->type_legacy == CMP_NODE_TEXTURE) {
157 PointerRNA ptr = RNA_pointer_create_discrete(&ntree->id, &RNA_Node, node);
158 PropertyRNA *prop = RNA_struct_find_property(&ptr, "texture");
160 users, id, ntree, node, ptr, prop, category, RNA_struct_ui_icon(ptr.type), node->name);
161 }
162 else if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
163 PointerRNA ptr = RNA_pointer_create_discrete(&ntree->id, &RNA_Node, node);
165 id,
166 ntree,
167 node,
168 {},
169 nullptr,
170 category,
172 node->name);
173 }
174 else if (node->is_group() && node->id) {
175 buttons_texture_users_find_nodetree(users, id, (bNodeTree *)node->id, category);
176 }
177 }
178 }
179}
180
182 Object *ob,
184 bNodeTree *node_tree,
186 blender::Set<const bNodeTree *> &handled_groups)
187{
188 PropertyRNA *prop;
189
190 for (bNode *node : node_tree->all_nodes()) {
191 if (node->is_group() && node->id) {
192 if (handled_groups.add(reinterpret_cast<bNodeTree *>(node->id))) {
193 /* Recurse into the node group */
195 ob, nmd, (bNodeTree *)node->id, users, handled_groups);
196 }
197 }
198 LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
199 if (socket->flag & SOCK_UNAVAIL) {
200 continue;
201 }
202 if (socket->type != SOCK_TEXTURE) {
203 continue;
204 }
205 PointerRNA ptr = RNA_pointer_create_discrete(&node_tree->id, &RNA_NodeSocket, socket);
206 prop = RNA_struct_find_property(&ptr, "default_value");
207
208 PointerRNA texptr = RNA_property_pointer_get(&ptr, prop);
209 Tex *tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? (Tex *)texptr.data : nullptr;
210 if (tex != nullptr) {
212 &ob->id,
213 ptr,
214 prop,
215 node_tree,
216 node,
217 socket,
218 N_("Geometry Nodes"),
220 nmd->modifier.name);
221 }
222 }
223 }
224}
225
226static void buttons_texture_modifier_foreach(void *user_data,
227 Object *ob,
228 ModifierData *md,
229 const PointerRNA *ptr,
230 PropertyRNA *texture_prop)
231{
232 ListBase *users = static_cast<ListBase *>(user_data);
233
234 if (md->type == eModifierType_Nodes) {
236 if (nmd->node_group != nullptr) {
237 blender::Set<const bNodeTree *> handled_groups;
238 buttons_texture_modifier_geonodes_users_add(ob, nmd, nmd->node_group, users, handled_groups);
239 }
240 }
241 else {
242 const ModifierTypeInfo *modifier_type = BKE_modifier_get_info((ModifierType)md->type);
243
245 users, &ob->id, *ptr, texture_prop, N_("Modifiers"), modifier_type->icon, md->name);
246 }
247}
248
250 const bContext *C,
251 SpaceProperties *sbuts)
252{
253 Scene *scene = nullptr;
254 Object *ob = nullptr;
255 FreestyleLineStyle *linestyle = nullptr;
256 Brush *brush = nullptr;
257 ID *pinid = sbuts->pinid;
258 bool limited_mode = (sbuts->flag & SB_TEX_USER_LIMITED) != 0;
259
260 /* get data from context */
261 if (pinid) {
262 if (GS(pinid->name) == ID_SCE) {
263 scene = (Scene *)pinid;
264 }
265 else if (GS(pinid->name) == ID_OB) {
266 ob = (Object *)pinid;
267 }
268 else if (GS(pinid->name) == ID_BR) {
269 brush = reinterpret_cast<Brush *>(pinid);
270 }
271 else if (GS(pinid->name) == ID_LS) {
272 linestyle = (FreestyleLineStyle *)pinid;
273 }
274 }
275
276 if (!scene) {
277 scene = CTX_data_scene(C);
278 }
279
280 const ID_Type id_type = ID_Type(pinid != nullptr ? GS(pinid->name) : -1);
281 if (!pinid || id_type == ID_SCE) {
282 wmWindow *win = CTX_wm_window(C);
283 ViewLayer *view_layer = (win->scene == scene) ? WM_window_get_active_view_layer(win) :
285
287 linestyle = BKE_linestyle_active_from_view_layer(view_layer);
288 BKE_view_layer_synced_ensure(scene, view_layer);
289 ob = BKE_view_layer_active_object_get(view_layer);
290 }
291
292 /* fill users */
294
295 if (scene && scene->nodetree) {
296 buttons_texture_users_find_nodetree(users, &scene->id, scene->nodetree, N_("Compositor"));
297 }
298
299 if (linestyle && !limited_mode) {
300 for (int i = 0; i < MAX_MTEX; i++) {
301 if (linestyle->mtex[i] && linestyle->mtex[i]->tex) {
302 buttons_texture_user_mtex_add(users, &linestyle->id, linestyle->mtex[i], N_("Line Style"));
303 }
304 }
306 users, &linestyle->id, linestyle->nodetree, N_("Line Style"));
307 }
308
309 if (ob) {
311 MTex *mtex;
312 int a;
313
314 /* modifiers */
316
317 /* particle systems */
318 if (psys && !limited_mode) {
319 for (a = 0; a < MAX_MTEX; a++) {
320 mtex = psys->part->mtex[a];
321
322 if (mtex) {
323 PropertyRNA *prop;
324
326 &psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex);
327 prop = RNA_struct_find_property(&ptr, "texture");
328
330 &psys->part->id,
331 ptr,
332 prop,
333 N_("Particles"),
334 RNA_struct_ui_icon(&RNA_ParticleSettings),
335 psys->name);
336 }
337 }
338 }
339
340 /* field */
341 if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) {
342 PropertyRNA *prop;
343
344 PointerRNA ptr = RNA_pointer_create_discrete(&ob->id, &RNA_FieldSettings, ob->pd);
345 prop = RNA_struct_find_property(&ptr, "texture");
346
348 users, &ob->id, ptr, prop, N_("Fields"), ICON_FORCE_TEXTURE, IFACE_("Texture Field"));
349 }
350 }
351
352 /* brush */
353 if (brush) {
354 PropertyRNA *prop;
355
356 /* texture */
357 PointerRNA ptr = RNA_pointer_create_discrete(&brush->id, &RNA_BrushTextureSlot, &brush->mtex);
358 prop = RNA_struct_find_property(&ptr, "texture");
359
361 users, &brush->id, ptr, prop, N_("Brush"), ICON_BRUSH_DATA, IFACE_("Brush"));
362
363 /* mask texture */
364 ptr = RNA_pointer_create_discrete(&brush->id, &RNA_BrushTextureSlot, &brush->mask_mtex);
365 prop = RNA_struct_find_property(&ptr, "texture");
366
368 users, &brush->id, ptr, prop, N_("Brush"), ICON_BRUSH_DATA, IFACE_("Brush Mask"));
369 }
370}
371
373{
374 /* gather available texture users in context. runs on every draw of
375 * properties editor, before the buttons are created. */
376 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
377 ID *pinid = sbuts->pinid;
378
379 if (!ct) {
380 ct = MEM_callocN<ButsContextTexture>("ButsContextTexture");
381 sbuts->texuser = ct;
382 }
383 else {
385 MEM_delete(user);
386 }
388 }
389
391
392 if (pinid && GS(pinid->name) == ID_TE) {
393 ct->user = nullptr;
394 ct->texture = (Tex *)pinid;
395 }
396 else {
397 /* set one user as active based on active index */
398 if (ct->index >= BLI_listbase_count_at_most(&ct->users, ct->index + 1)) {
399 ct->index = 0;
400 }
401
402 ct->user = static_cast<ButsTextureUser *>(BLI_findlink(&ct->users, ct->index));
403 ct->texture = nullptr;
404
405 if (ct->user) {
406 if (ct->user->node != nullptr) {
407 /* Detect change of active texture node in same node tree, in that
408 * case we also automatically switch to the other node. */
409 if ((ct->user->node->flag & NODE_ACTIVE_TEXTURE) == 0) {
410 LISTBASE_FOREACH (ButsTextureUser *, user, &ct->users) {
411 if (user->ntree == ct->user->ntree && user->node != ct->user->node) {
412 if (user->node->flag & NODE_ACTIVE_TEXTURE) {
413 ct->user = user;
414 ct->index = BLI_findindex(&ct->users, user);
415 break;
416 }
417 }
418 }
419 }
420 }
421 if (ct->user->ptr.data) {
422 PointerRNA texptr;
423 Tex *tex;
424
425 /* Get texture datablock pointer if it's a property. */
426 texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop);
427 tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? static_cast<Tex *>(texptr.data) :
428 nullptr;
429
430 ct->texture = tex;
431 }
432 }
433 }
434}
435
436static void template_texture_select(bContext *C, void *user_p, void * /*arg*/)
437{
438 /* callback when selecting a texture user in the menu */
440 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
441 ButsTextureUser *user = (ButsTextureUser *)user_p;
442 PointerRNA texptr;
443 Tex *tex;
444
445 if (!ct) {
446 return;
447 }
448
449 /* set user as active */
450 if (user->node) {
451 ED_node_set_active(CTX_data_main(C), nullptr, user->ntree, user->node, nullptr);
452 ct->texture = nullptr;
453
454 /* Not totally sure if we should also change selection? */
455 for (bNode *node : user->ntree->all_nodes()) {
457 }
460 }
461 if (user->ptr.data) {
462 texptr = RNA_property_pointer_get(&user->ptr, user->prop);
463 tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? static_cast<Tex *>(texptr.data) : nullptr;
464
465 ct->texture = tex;
466
467 if (user->ptr.type == &RNA_ParticleSettingsTextureSlot) {
468 /* stupid exception for particle systems which still uses influence
469 * from the old texture system, set the active texture slots as well */
471 int a;
472
473 for (a = 0; a < MAX_MTEX; a++) {
474 if (user->ptr.data == part->mtex[a]) {
475 part->texact = a;
476 }
477 }
478 }
479
480 if (sbuts && tex) {
481 sbuts->preview = 1;
482 }
483 }
484
485 ct->user = user;
486 ct->index = user->index;
487}
488
489static void template_texture_user_menu(bContext *C, uiLayout *layout, void * /*arg*/)
490{
491 /* callback when opening texture user selection menu, to create buttons. */
493 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
494 uiBlock *block = uiLayoutGetBlock(layout);
495 const char *last_category = nullptr;
496
497 LISTBASE_FOREACH (ButsTextureUser *, user, &ct->users) {
498 uiBut *but;
499 char name[UI_MAX_NAME_STR];
500
501 /* add label per category */
502 if (!last_category || !STREQ(last_category, user->category)) {
503 layout->label(IFACE_(user->category), ICON_NONE);
504 but = block->buttons.last().get();
506 }
507
508 /* create button */
509 if (user->prop) {
510 PointerRNA texptr = RNA_property_pointer_get(&user->ptr, user->prop);
511 Tex *tex = static_cast<Tex *>(texptr.data);
512
513 if (tex) {
514 SNPRINTF(name, " %s - %s", user->name, tex->id.name + 2);
515 }
516 else {
517 SNPRINTF(name, " %s", user->name);
518 }
519 }
520 else {
521 SNPRINTF(name, " %s", user->name);
522 }
523
524 but = uiDefIconTextBut(block,
526 0,
527 user->icon,
528 name,
529 0,
530 0,
531 UI_UNIT_X * 4,
532 UI_UNIT_Y,
533 nullptr,
534 0.0,
535 0.0,
536 "");
539 MEM_new<ButsTextureUser>("ButsTextureUser", *user),
540 nullptr,
543
544 last_category = user->category;
545 }
546}
547
549{
550 /* Texture user selection drop-down menu. the available users have been
551 * gathered before drawing in #ButsContextTexture, we merely need to
552 * display the current item. */
554 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
555 uiBlock *block = uiLayoutGetBlock(layout);
556 uiBut *but;
557 ButsTextureUser *user;
558 char name[UI_MAX_NAME_STR];
559
560 if (!ct) {
561 return;
562 }
563
564 /* get current user */
565 user = ct->user;
566
567 if (!user) {
568 layout->label(TIP_("No textures in context"), ICON_NONE);
569 return;
570 }
571
572 /* create button */
573 STRNCPY(name, user->name);
574
575 if (user->icon) {
576 but = uiDefIconTextMenuBut(block,
578 nullptr,
579 user->icon,
580 name,
581 0,
582 0,
583 UI_UNIT_X * 4,
584 UI_UNIT_Y,
585 "");
586 }
587 else {
588 but = uiDefMenuBut(
589 block, template_texture_user_menu, nullptr, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, "");
590 }
591
592 /* some cosmetic tweaks */
594
596}
597
598/************************* Texture Show **************************/
599
601{
602 bScreen *screen = CTX_wm_screen(C);
604
605 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
606 if (area->spacetype == SPACE_PROPERTIES) {
607 /* Only if unpinned, or if pinned object matches. */
608 SpaceProperties *sbuts = static_cast<SpaceProperties *>(area->spacedata.first);
609 ID *pinid = sbuts->pinid;
610 if (pinid == nullptr || ((GS(pinid->name) == ID_OB) && (Object *)pinid == ob)) {
611 return area;
612 }
613 }
614 }
615
616 return nullptr;
617}
618
620{
622 if (area != nullptr) {
623 return static_cast<SpaceProperties *>(area->spacedata.first);
624 }
625
626 return nullptr;
627}
628
629static void template_texture_show(bContext *C, void *data_p, void *prop_p)
630{
631 if (data_p == nullptr || prop_p == nullptr) {
632 return;
633 }
634
636 if (area == nullptr) {
637 return;
638 }
639
641 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
642 if (!ct) {
643 return;
644 }
645
646 ButsTextureUser *user;
647 for (user = static_cast<ButsTextureUser *>(ct->users.first); user; user = user->next) {
648 if (user->ptr.data == data_p && user->prop == prop_p) {
649 break;
650 }
651 }
652
653 if (user) {
654 /* select texture */
655 template_texture_select(C, user, nullptr);
656
657 /* change context */
658 sbuts->mainb = BCONTEXT_TEXTURE;
659 sbuts->mainbuser = sbuts->mainb;
660 sbuts->preview = 1;
661
662 /* redraw editor */
663 ED_area_tag_redraw(area);
664 }
665}
666
668{
669 /* Only show the button if there is actually a texture assigned. */
670 Tex *texture = static_cast<Tex *>(RNA_property_pointer_get(ptr, prop).data);
671 if (texture == nullptr) {
672 return;
673 }
674
675 /* Only show the button if we are not in the Properties Editor's texture tab. */
676 SpaceProperties *sbuts_context = CTX_wm_space_properties(C);
677 if (sbuts_context != nullptr && sbuts_context->mainb == BCONTEXT_TEXTURE) {
678 return;
679 }
680
682 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
683
684 /* find corresponding texture user */
685 ButsTextureUser *user;
686 bool user_found = false;
687 if (ct != nullptr) {
688 for (user = static_cast<ButsTextureUser *>(ct->users.first); user; user = user->next) {
689 if (user->ptr.data == ptr->data && user->prop == prop) {
690 user_found = true;
691 break;
692 }
693 }
694 }
695
696 /* Draw button (disabled if we cannot find a Properties Editor to display this in). */
697 uiBlock *block = uiLayoutGetBlock(layout);
698 uiBut *but;
699 but = uiDefIconBut(block,
701 0,
702 ICON_PROPERTIES,
703 0,
704 0,
705 UI_UNIT_X,
706 UI_UNIT_Y,
707 nullptr,
708 0.0,
709 0.0,
710 TIP_("Show texture in texture tab"));
711 UI_but_func_set(but,
713 user_found ? user->ptr.data : nullptr,
714 user_found ? user->prop : nullptr);
715 if (ct == nullptr) {
716 UI_but_disable(but, "No (unpinned) Properties Editor found to display texture in");
717 }
718 else if (!user_found) {
719 UI_but_disable(but, "No texture user found");
720 }
721}
bScreen * CTX_wm_screen(const bContext *C)
SpaceProperties * CTX_wm_space_properties(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ViewLayer * BKE_view_layer_default_view(const Scene *scene)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
const char * BKE_id_name(const ID &id)
Blender kernel freestyle line style functionality.
FreestyleLineStyle * BKE_linestyle_active_from_view_layer(struct ViewLayer *view_layer)
Definition linestyle.cc:704
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *user_data)
#define NODE_CLASS_TEXTURE
Definition BKE_node.hh:443
#define CMP_NODE_TEXTURE
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:467
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:636
struct ParticleSystem * psys_get_current(struct Object *ob)
Definition particle.cc:537
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
int BLI_listbase_count_at_most(const ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:511
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define STREQ(a, b)
#define TIP_(msgid)
#define IFACE_(msgid)
ID and Library types, which are fundamental for SDNA.
ID_Type
@ ID_TE
@ ID_SCE
@ ID_LS
@ ID_BR
@ ID_OB
@ eModifierType_Nodes
@ NODE_ACTIVE_TEXTURE
@ SOCK_UNAVAIL
@ SOCK_TEXTURE
Object is a sort of wrapper for general info.
@ SPACE_PROPERTIES
@ SB_TEX_USER_LIMITED
@ BCONTEXT_TEXTURE
void ED_node_set_active(Main *bmain, SpaceNode *snode, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
Definition node_edit.cc:772
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:714
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
#define MAX_MTEX
Definition Stroke.h:31
void UI_but_func_set(uiBut *but, std::function< void(bContext &)> func)
void * but_func_argN_copy(const void *argN)
void but_func_argN_free(void *argN)
void UI_but_disable(uiBut *but, const char *disabled_hint)
#define UI_UNIT_Y
uiBut * uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
uiBut * uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, blender::StringRef str, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
uiBut * uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, blender::StringRef str, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
void UI_but_type_set_menu_from_pulldown(uiBut *but)
uiBut * uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
@ UI_BUT_TEXT_LEFT
#define UI_UNIT_X
@ UI_BTYPE_BUT
@ UI_BUT_ICON_SUBMENU
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2, uiButArgNFree func_argN_free_fn=MEM_freeN, uiButArgNCopy func_argN_copy_fn=MEM_dupallocN)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
#define UI_MAX_NAME_STR
#define NC_NODE
Definition WM_types.hh:391
#define NA_SELECTED
Definition WM_types.hh:586
static void template_texture_show(bContext *C, void *data_p, void *prop_p)
static void buttons_texture_modifier_foreach(void *user_data, Object *ob, ModifierData *md, const PointerRNA *ptr, PropertyRNA *texture_prop)
void uiTemplateTextureUser(uiLayout *layout, bContext *C)
static void buttons_texture_user_socket_property_add(ListBase *users, ID *id, PointerRNA ptr, PropertyRNA *prop, bNodeTree *ntree, bNode *node, bNodeSocket *socket, const char *category, int icon, const char *name)
static void buttons_texture_user_mtex_add(ListBase *users, ID *id, MTex *mtex, const char *category)
static void buttons_texture_user_property_add(ListBase *users, ID *id, PointerRNA ptr, PropertyRNA *prop, const char *category, int icon, const char *name)
static void buttons_texture_user_node_add(ListBase *users, ID *id, bNodeTree *ntree, bNode *node, PointerRNA ptr, PropertyRNA *prop, const char *category, int icon, const char *name)
static ScrArea * find_area_properties(const bContext *C)
static void buttons_texture_modifier_geonodes_users_add(Object *ob, NodesModifierData *nmd, bNodeTree *node_tree, ListBase *users, blender::Set< const bNodeTree * > &handled_groups)
static SpaceProperties * find_space_properties(const bContext *C)
void uiTemplateTextureShow(uiLayout *layout, const bContext *C, PointerRNA *ptr, PropertyRNA *prop)
static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceProperties *sbuts)
void buttons_texture_context_compute(const bContext *C, SpaceProperties *sbuts)
static void template_texture_select(bContext *C, void *user_p, void *)
static void template_texture_user_menu(bContext *C, uiLayout *layout, void *)
static void buttons_texture_users_find_nodetree(ListBase *users, ID *id, bNodeTree *ntree, const char *category)
const T & last(const int64_t n=0) const
bool add(const Key &key)
Definition BLI_set.hh:248
int users
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
#define GS(a)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
bool node_set_selected(bNode &node, bool select)
Definition node.cc:4967
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_struct_ui_icon(const StructRNA *type)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
struct MTex mtex
struct MTex mask_mtex
struct ButsTextureUser * user
const char * category
ButsTextureUser * next
bNodeTree * ntree
const char * name
bNodeSocket * socket
PropertyRNA * prop
struct bNodeTree * nodetree
struct MTex * mtex[18]
Definition DNA_ID.h:404
char name[66]
Definition DNA_ID.h:415
void * first
struct Tex * tex
struct bNodeTree * node_group
struct PartDeflect * pd
struct MTex * mtex[18]
ParticleSettings * part
ID * owner_id
Definition RNA_types.hh:51
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
const char * name
struct bNodeTree * nodetree
ListBase spacedata
ListBase areabase
blender::Vector< std::unique_ptr< uiBut > > buttons
void label(blender::StringRef name, int icon)
struct Scene * scene
i
Definition text_draw.cc:230
#define N_(msgid)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4227
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)