Blender V5.0
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_utf8.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
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->typeinfo->nclass == NODE_CLASS_TEXTURE) {
157 PointerRNA ptr = RNA_pointer_create_discrete(&ntree->id, &RNA_Node, node);
159 id,
160 ntree,
161 node,
162 {},
163 nullptr,
164 category,
166 node->name);
167 }
168 else if (node->is_group() && node->id) {
169 buttons_texture_users_find_nodetree(users, id, (bNodeTree *)node->id, category);
170 }
171 }
172 }
173}
174
176 Object *ob,
178 bNodeTree *node_tree,
180 blender::Set<const bNodeTree *> &handled_groups)
181{
182 PropertyRNA *prop;
183
184 for (bNode *node : node_tree->all_nodes()) {
185 if (node->is_group() && node->id) {
186 if (handled_groups.add(reinterpret_cast<bNodeTree *>(node->id))) {
187 /* Recurse into the node group */
189 ob, nmd, (bNodeTree *)node->id, users, handled_groups);
190 }
191 }
192 LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
193 if (socket->flag & SOCK_UNAVAIL) {
194 continue;
195 }
196 if (socket->type != SOCK_TEXTURE) {
197 continue;
198 }
199 PointerRNA ptr = RNA_pointer_create_discrete(&node_tree->id, &RNA_NodeSocket, socket);
200 prop = RNA_struct_find_property(&ptr, "default_value");
201
202 PointerRNA texptr = RNA_property_pointer_get(&ptr, prop);
203 Tex *tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? (Tex *)texptr.data : nullptr;
204 if (tex != nullptr) {
206 &ob->id,
207 ptr,
208 prop,
209 node_tree,
210 node,
211 socket,
212 N_("Geometry Nodes"),
214 nmd->modifier.name);
215 }
216 }
217 }
218}
219
220static void buttons_texture_modifier_foreach(void *user_data,
221 Object *ob,
222 ModifierData *md,
223 const PointerRNA *ptr,
224 PropertyRNA *texture_prop)
225{
226 ListBase *users = static_cast<ListBase *>(user_data);
227
228 if (md->type == eModifierType_Nodes) {
230 if (nmd->node_group != nullptr) {
231 blender::Set<const bNodeTree *> handled_groups;
232 buttons_texture_modifier_geonodes_users_add(ob, nmd, nmd->node_group, users, handled_groups);
233 }
234 }
235 else {
236 const ModifierTypeInfo *modifier_type = BKE_modifier_get_info((ModifierType)md->type);
237
239 users, &ob->id, *ptr, texture_prop, N_("Modifiers"), modifier_type->icon, md->name);
240 }
241}
242
244 const bContext *C,
245 SpaceProperties *sbuts)
246{
247 Scene *scene = nullptr;
248 Object *ob = nullptr;
249 FreestyleLineStyle *linestyle = nullptr;
250 Brush *brush = nullptr;
251 ID *pinid = sbuts->pinid;
252 bool limited_mode = (sbuts->flag & SB_TEX_USER_LIMITED) != 0;
253
254 /* get data from context */
255 if (pinid) {
256 if (GS(pinid->name) == ID_SCE) {
257 scene = (Scene *)pinid;
258 }
259 else if (GS(pinid->name) == ID_OB) {
260 ob = (Object *)pinid;
261 }
262 else if (GS(pinid->name) == ID_BR) {
263 brush = reinterpret_cast<Brush *>(pinid);
264 }
265 else if (GS(pinid->name) == ID_LS) {
266 linestyle = (FreestyleLineStyle *)pinid;
267 }
268 }
269
270 if (!scene) {
271 scene = CTX_data_scene(C);
272 }
273
274 const ID_Type id_type = ID_Type(pinid != nullptr ? GS(pinid->name) : -1);
275 if (!pinid || id_type == ID_SCE) {
276 wmWindow *win = CTX_wm_window(C);
277 ViewLayer *view_layer = (win->scene == scene) ? WM_window_get_active_view_layer(win) :
279
281 linestyle = BKE_linestyle_active_from_view_layer(view_layer);
282 BKE_view_layer_synced_ensure(scene, view_layer);
283 ob = BKE_view_layer_active_object_get(view_layer);
284 }
285
286 /* fill users */
288
289 if (scene && scene->compositing_node_group) {
291 users, &scene->id, scene->compositing_node_group, N_("Compositor"));
292 }
293
294 if (linestyle && !limited_mode) {
295 for (int i = 0; i < MAX_MTEX; i++) {
296 if (linestyle->mtex[i] && linestyle->mtex[i]->tex) {
297 buttons_texture_user_mtex_add(users, &linestyle->id, linestyle->mtex[i], N_("Line Style"));
298 }
299 }
301 users, &linestyle->id, linestyle->nodetree, N_("Line Style"));
302 }
303
304 if (ob) {
306 MTex *mtex;
307 int a;
308
309 /* modifiers */
311
312 /* particle systems */
313 if (psys && !limited_mode) {
314 for (a = 0; a < MAX_MTEX; a++) {
315 mtex = psys->part->mtex[a];
316
317 if (mtex) {
318 PropertyRNA *prop;
319
321 &psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex);
322 prop = RNA_struct_find_property(&ptr, "texture");
323
325 &psys->part->id,
326 ptr,
327 prop,
328 N_("Particles"),
329 RNA_struct_ui_icon(&RNA_ParticleSettings),
330 psys->name);
331 }
332 }
333 }
334
335 /* field */
336 if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) {
337 PropertyRNA *prop;
338
339 PointerRNA ptr = RNA_pointer_create_discrete(&ob->id, &RNA_FieldSettings, ob->pd);
340 prop = RNA_struct_find_property(&ptr, "texture");
341
343 users, &ob->id, ptr, prop, N_("Fields"), ICON_FORCE_TEXTURE, IFACE_("Texture Field"));
344 }
345 }
346
347 /* brush */
348 if (brush) {
349 PropertyRNA *prop;
350
351 /* texture */
352 PointerRNA ptr = RNA_pointer_create_discrete(&brush->id, &RNA_BrushTextureSlot, &brush->mtex);
353 prop = RNA_struct_find_property(&ptr, "texture");
354
356 users, &brush->id, ptr, prop, N_("Brush"), ICON_BRUSH_DATA, IFACE_("Brush"));
357
358 /* mask texture */
359 ptr = RNA_pointer_create_discrete(&brush->id, &RNA_BrushTextureSlot, &brush->mask_mtex);
360 prop = RNA_struct_find_property(&ptr, "texture");
361
363 users, &brush->id, ptr, prop, N_("Brush"), ICON_BRUSH_DATA, IFACE_("Brush Mask"));
364 }
365}
366
368{
369 /* gather available texture users in context. runs on every draw of
370 * properties editor, before the buttons are created. */
371 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
372 ID *pinid = sbuts->pinid;
373
374 if (!ct) {
375 ct = MEM_callocN<ButsContextTexture>("ButsContextTexture");
376 sbuts->texuser = ct;
377 }
378 else {
380 MEM_delete(user);
381 }
383 }
384
386
387 if (pinid && GS(pinid->name) == ID_TE) {
388 ct->user = nullptr;
389 ct->texture = (Tex *)pinid;
390 }
391 else {
392 /* set one user as active based on active index */
393 if (ct->index >= BLI_listbase_count_at_most(&ct->users, ct->index + 1)) {
394 ct->index = 0;
395 }
396
397 ct->user = static_cast<ButsTextureUser *>(BLI_findlink(&ct->users, ct->index));
398 ct->texture = nullptr;
399
400 if (ct->user) {
401 if (ct->user->node != nullptr) {
402 /* Detect change of active texture node in same node tree, in that
403 * case we also automatically switch to the other node. */
404 if ((ct->user->node->flag & NODE_ACTIVE_TEXTURE) == 0) {
405 LISTBASE_FOREACH (ButsTextureUser *, user, &ct->users) {
406 if (user->ntree == ct->user->ntree && user->node != ct->user->node) {
407 if (user->node->flag & NODE_ACTIVE_TEXTURE) {
408 ct->user = user;
409 ct->index = BLI_findindex(&ct->users, user);
410 break;
411 }
412 }
413 }
414 }
415 }
416 if (ct->user->ptr.data) {
417 PointerRNA texptr;
418 Tex *tex;
419
420 /* Get texture datablock pointer if it's a property. */
421 texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop);
422 tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? static_cast<Tex *>(texptr.data) :
423 nullptr;
424
425 ct->texture = tex;
426 }
427 }
428 }
429}
430
431static void template_texture_select(bContext *C, void *user_p, void * /*arg*/)
432{
433 /* callback when selecting a texture user in the menu */
435 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
436 ButsTextureUser *user = (ButsTextureUser *)user_p;
437 PointerRNA texptr;
438 Tex *tex;
439
440 if (!ct) {
441 return;
442 }
443
444 /* set user as active */
445 if (user->node) {
446 ED_node_set_active(CTX_data_main(C), nullptr, user->ntree, user->node, nullptr);
447 ct->texture = nullptr;
448
449 /* Not totally sure if we should also change selection? */
450 for (bNode *node : user->ntree->all_nodes()) {
452 }
455 }
456 if (user->ptr.data) {
457 texptr = RNA_property_pointer_get(&user->ptr, user->prop);
458 tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? static_cast<Tex *>(texptr.data) : nullptr;
459
460 ct->texture = tex;
461
462 if (user->ptr.type == &RNA_ParticleSettingsTextureSlot) {
463 /* stupid exception for particle systems which still uses influence
464 * from the old texture system, set the active texture slots as well */
466 int a;
467
468 for (a = 0; a < MAX_MTEX; a++) {
469 if (user->ptr.data == part->mtex[a]) {
470 part->texact = a;
471 }
472 }
473 }
474
475 if (sbuts && tex) {
476 sbuts->preview = 1;
477 }
478 }
479
480 ct->user = user;
481 ct->index = user->index;
482}
483
484static void template_texture_user_menu(bContext *C, uiLayout *layout, void * /*arg*/)
485{
486 /* callback when opening texture user selection menu, to create buttons. */
488 ButsContextTexture *ct = static_cast<ButsContextTexture *>(sbuts->texuser);
489 uiBlock *block = layout->block();
490 const char *last_category = nullptr;
491
492 LISTBASE_FOREACH (ButsTextureUser *, user, &ct->users) {
493 uiBut *but;
494 char name[UI_MAX_NAME_STR];
495
496 /* add label per category */
497 if (!last_category || !STREQ(last_category, user->category)) {
498 layout->label(IFACE_(user->category), ICON_NONE);
499 but = block->buttons.last().get();
501 }
502
503 /* create button */
504 if (user->prop) {
505 PointerRNA texptr = RNA_property_pointer_get(&user->ptr, user->prop);
506 Tex *tex = static_cast<Tex *>(texptr.data);
507
508 if (tex) {
509 SNPRINTF_UTF8(name, " %s - %s", user->name, tex->id.name + 2);
510 }
511 else {
512 SNPRINTF_UTF8(name, " %s", user->name);
513 }
514 }
515 else {
516 SNPRINTF_UTF8(name, " %s", user->name);
517 }
518
519 but = uiDefIconTextBut(
520 block, ButType::But, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, nullptr, "");
523 MEM_new<ButsTextureUser>("ButsTextureUser", *user),
524 nullptr,
527
528 last_category = user->category;
529 }
530}
531
533{
534 /* Texture user selection drop-down menu. the available users have been
535 * gathered before drawing in #ButsContextTexture, we merely need to
536 * display the current item. */
538 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
539 uiBlock *block = layout->block();
540 uiBut *but;
541 ButsTextureUser *user;
542 char name[UI_MAX_NAME_STR];
543
544 if (!ct) {
545 return;
546 }
547
548 /* get current user */
549 user = ct->user;
550
551 if (!user) {
552 layout->label(TIP_("No textures in context"), ICON_NONE);
553 return;
554 }
555
556 /* create button */
557 STRNCPY_UTF8(name, user->name);
558
559 if (user->icon) {
560 but = uiDefIconTextMenuBut(block,
562 nullptr,
563 user->icon,
564 name,
565 0,
566 0,
567 UI_UNIT_X * 4,
568 UI_UNIT_Y,
569 "");
570 }
571 else {
572 but = uiDefMenuBut(
573 block, template_texture_user_menu, nullptr, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, "");
574 }
575
576 /* some cosmetic tweaks */
578
580}
581
582/************************* Texture Show **************************/
583
585{
586 bScreen *screen = CTX_wm_screen(C);
588
589 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
590 if (area->spacetype == SPACE_PROPERTIES) {
591 /* Only if unpinned, or if pinned object matches. */
592 SpaceProperties *sbuts = static_cast<SpaceProperties *>(area->spacedata.first);
593 ID *pinid = sbuts->pinid;
594 if (pinid == nullptr || ((GS(pinid->name) == ID_OB) && (Object *)pinid == ob)) {
595 return area;
596 }
597 }
598 }
599
600 return nullptr;
601}
602
604{
606 if (area != nullptr) {
607 return static_cast<SpaceProperties *>(area->spacedata.first);
608 }
609
610 return nullptr;
611}
612
613static void template_texture_show(bContext *C, void *data_p, void *prop_p)
614{
615 if (data_p == nullptr || prop_p == nullptr) {
616 return;
617 }
618
620 if (area == nullptr) {
621 return;
622 }
623
625 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
626 if (!ct) {
627 return;
628 }
629
630 ButsTextureUser *user;
631 for (user = static_cast<ButsTextureUser *>(ct->users.first); user; user = user->next) {
632 if (user->ptr.data == data_p && user->prop == prop_p) {
633 break;
634 }
635 }
636
637 if (user) {
638 /* select texture */
639 template_texture_select(C, user, nullptr);
640
641 /* change context */
642 sbuts->mainb = BCONTEXT_TEXTURE;
643 sbuts->mainbuser = sbuts->mainb;
644 sbuts->preview = 1;
645
646 /* redraw editor */
647 ED_area_tag_redraw(area);
648 }
649}
650
652{
653 /* Only show the button if there is actually a texture assigned. */
654 Tex *texture = static_cast<Tex *>(RNA_property_pointer_get(ptr, prop).data);
655 if (texture == nullptr) {
656 return;
657 }
658
659 /* Only show the button if we are not in the Properties Editor's texture tab. */
660 SpaceProperties *sbuts_context = CTX_wm_space_properties(C);
661 if (sbuts_context != nullptr && sbuts_context->mainb == BCONTEXT_TEXTURE) {
662 return;
663 }
664
666 ButsContextTexture *ct = (sbuts) ? static_cast<ButsContextTexture *>(sbuts->texuser) : nullptr;
667
668 /* find corresponding texture user */
669 ButsTextureUser *user;
670 bool user_found = false;
671 if (ct != nullptr) {
672 for (user = static_cast<ButsTextureUser *>(ct->users.first); user; user = user->next) {
673 if (user->ptr.data == ptr->data && user->prop == prop) {
674 user_found = true;
675 break;
676 }
677 }
678 }
679
680 /* Draw button (disabled if we cannot find a Properties Editor to display this in). */
681 uiBlock *block = layout->block();
682 uiBut *but;
683 but = uiDefIconBut(block,
685 0,
686 ICON_PROPERTIES,
687 0,
688 0,
689 UI_UNIT_X,
690 UI_UNIT_Y,
691 nullptr,
692 0.0,
693 0.0,
694 TIP_("Show texture in texture tab"));
695 UI_but_func_set(but,
697 user_found ? user->ptr.data : nullptr,
698 user_found ? user->prop : nullptr);
699 if (ct == nullptr) {
700 UI_but_disable(but, "No (unpinned) Properties Editor found to display texture in");
701 }
702 else if (!user_found) {
703 UI_but_disable(but, "No texture user found");
704 }
705}
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:714
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:457
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:476
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:645
struct ParticleSystem * psys_get_current(struct Object *ob)
Definition particle.cc:538
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_UTF8(dst, format,...)
#define STRNCPY_UTF8(dst, src)
#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:728
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:693
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)
uiBut * uiDefIconTextBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, int icon, blender::StringRef str, int x, int y, short width, short height, void *poin, std::optional< blender::StringRef > tip)
#define UI_UNIT_Y
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)
@ UI_BUT_ICON_SUBMENU
uiBut * uiDefIconBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
void UI_but_type_set_menu_from_pulldown(uiBut *but)
#define UI_UNIT_X
@ UI_BUT_TEXT_LEFT
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)
#define UI_MAX_NAME_STR
#define NC_NODE
Definition WM_types.hh:394
#define NA_SELECTED
Definition WM_types.hh:589
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
#define GS(x)
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
bool node_set_selected(bNode &node, bool select)
Definition node.cc:4695
const char * name
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:414
char name[258]
Definition DNA_ID.h:432
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
struct bNodeTree * compositing_node_group
ListBase spacedata
ListBase areabase
blender::Vector< std::unique_ptr< uiBut > > buttons
uiBlock * block() const
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:4238
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)