/blender-2.63a/source/blender/editors/interface/interface_templates.c
C | 2744 lines | 1943 code | 531 blank | 270 comment | 525 complexity | 618cad00d3cbe6ae7d73caa7a245fe66 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-3.0, BSD-2-Clause, Apache-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Blender Foundation 2009.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
- /** \file blender/editors/interface/interface_templates.c
- * \ingroup edinterface
- */
- #include <stdlib.h>
- #include <stddef.h>
- #include <string.h>
- #include "MEM_guardedalloc.h"
- #include "DNA_anim_types.h"
- #include "DNA_dynamicpaint_types.h"
- #include "DNA_key_types.h"
- #include "DNA_scene_types.h"
- #include "DNA_userdef_types.h"
- #include "BLI_utildefines.h"
- #include "BLI_string.h"
- #include "BLI_ghash.h"
- #include "BLF_translation.h"
- #include "BKE_animsys.h"
- #include "BKE_colortools.h"
- #include "BKE_context.h"
- #include "BKE_dynamicpaint.h"
- #include "BKE_global.h"
- #include "BKE_library.h"
- #include "BKE_main.h"
- #include "BKE_object.h"
- #include "BKE_material.h"
- #include "BKE_texture.h"
- #include "BKE_report.h"
- #include "BKE_displist.h"
- #include "BKE_scene.h"
- #include "ED_screen.h"
- #include "ED_object.h"
- #include "ED_render.h"
- #include "RNA_access.h"
- #include "RNA_enum_types.h"
- #include "WM_api.h"
- #include "WM_types.h"
- #include "UI_interface.h"
- #include "interface_intern.h"
- #include "BLF_api.h"
- #include "BLF_translation.h"
- void UI_template_fix_linking(void)
- {
- }
- /********************** Header Template *************************/
- void uiTemplateHeader(uiLayout *layout, bContext *C, int menus)
- {
- uiBlock *block;
- block = uiLayoutAbsoluteBlock(layout);
- if (menus) ED_area_header_standardbuttons(C, block, 0);
- else ED_area_header_switchbutton(C, block, 0);
- }
- /********************** Search Callbacks *************************/
- typedef struct TemplateID {
- PointerRNA ptr;
- PropertyRNA *prop;
- ListBase *idlb;
- int prv_rows, prv_cols;
- int preview;
- } TemplateID;
- /* Search browse menu, assign */
- static void id_search_call_cb(bContext *C, void *arg_template, void *item)
- {
- TemplateID *template = (TemplateID *)arg_template;
- /* ID */
- if (item) {
- PointerRNA idptr;
- RNA_id_pointer_create(item, &idptr);
- RNA_property_pointer_set(&template->ptr, template->prop, idptr);
- RNA_property_update(C, &template->ptr, template->prop);
- }
- }
- /* ID Search browse menu, do the search */
- static void id_search_cb(const bContext *C, void *arg_template, const char *str, uiSearchItems *items)
- {
- TemplateID *template = (TemplateID *)arg_template;
- ListBase *lb = template->idlb;
- ID *id, *id_from = template->ptr.id.data;
- int iconid;
- int flag = RNA_property_flag(template->prop);
- /* ID listbase */
- for (id = lb->first; id; id = id->next) {
- if (!((flag & PROP_ID_SELF_CHECK) && id == id_from)) {
- /* use filter */
- if (RNA_property_type(template->prop) == PROP_POINTER) {
- PointerRNA ptr;
- RNA_id_pointer_create(id, &ptr);
- if (RNA_property_pointer_poll(&template->ptr, template->prop, &ptr) == 0)
- continue;
- }
- /* hide dot-datablocks, but only if filter does not force it visible */
- if (U.uiflag & USER_HIDE_DOT)
- if ((id->name[2] == '.') && (str[0] != '.'))
- continue;
- if (BLI_strcasestr(id->name + 2, str)) {
- char name_ui[MAX_ID_NAME];
- name_uiprefix_id(name_ui, id);
- iconid = ui_id_icon_get((bContext *)C, id, template->preview);
- if (!uiSearchItemAdd(items, name_ui, id, iconid))
- break;
- }
- }
- }
- }
- /* ID Search browse menu, open */
- static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
- {
- static char search[256];
- static TemplateID template;
- PointerRNA idptr;
- wmWindow *win = CTX_wm_window(C);
- uiBlock *block;
- uiBut *but;
-
- /* clear initial search string, then all items show */
- search[0] = 0;
- /* arg_litem is malloced, can be freed by parent button */
- template = *((TemplateID *)arg_litem);
-
- /* get active id for showing first item */
- idptr = RNA_property_pointer_get(&template.ptr, template.prop);
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_RET_1);
-
- /* preview thumbnails */
- if (template.prv_rows > 0 && template.prv_cols > 0) {
- int w = 96 * template.prv_cols;
- int h = 96 * template.prv_rows + 20;
-
- /* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
-
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19, template.prv_rows, template.prv_cols, "");
- uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
- }
- /* list view */
- else {
- /* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
-
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
- uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
- }
-
-
- uiBoundsBlock(block, 6);
- uiBlockSetDirection(block, UI_DOWN);
- uiEndBlock(C, block);
-
- /* give search-field focus */
- uiButSetFocusOnEnter(win, but);
- /* this type of search menu requires undo */
- but->flag |= UI_BUT_UNDO;
-
- return block;
- }
- /************************ ID Template ***************************/
- /* This is for browsing and editing the ID-blocks used */
- /* for new/open operators */
- void uiIDContextProperty(bContext *C, PointerRNA *ptr, PropertyRNA **prop)
- {
- TemplateID *template;
- ARegion *ar = CTX_wm_region(C);
- uiBlock *block;
- uiBut *but;
- memset(ptr, 0, sizeof(*ptr));
- *prop = NULL;
- if (!ar)
- return;
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- /* find the button before the active one */
- if ((but->flag & (UI_BUT_LAST_ACTIVE | UI_ACTIVE))) {
- if (but->func_argN) {
- template = but->func_argN;
- *ptr = template->ptr;
- *prop = template->prop;
- return;
- }
- }
- }
- }
- }
- static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
- {
- TemplateID *template = (TemplateID *)arg_litem;
- PointerRNA idptr = RNA_property_pointer_get(&template->ptr, template->prop);
- ID *id = idptr.data;
- int event = GET_INT_FROM_POINTER(arg_event);
-
- switch (event) {
- case UI_ID_BROWSE:
- case UI_ID_PIN:
- RNA_warning("warning, id event %d shouldnt come here", event);
- break;
- case UI_ID_OPEN:
- case UI_ID_ADD_NEW:
- /* these call uiIDContextPropertySet */
- break;
- case UI_ID_DELETE:
- memset(&idptr, 0, sizeof(idptr));
- RNA_property_pointer_set(&template->ptr, template->prop, idptr);
- RNA_property_update(C, &template->ptr, template->prop);
- if (id && CTX_wm_window(C)->eventstate->shift) /* useful hidden functionality, */
- id->us = 0;
- break;
- case UI_ID_FAKE_USER:
- if (id) {
- if (id->flag & LIB_FAKEUSER) id_us_plus(id);
- else id_us_min(id);
- }
- else return;
- break;
- case UI_ID_LOCAL:
- if (id) {
- if (id_make_local(id, 0)) {
- /* reassign to get get proper updates/notifiers */
- idptr = RNA_property_pointer_get(&template->ptr, template->prop);
- RNA_property_pointer_set(&template->ptr, template->prop, idptr);
- RNA_property_update(C, &template->ptr, template->prop);
- }
- }
- break;
- case UI_ID_ALONE:
- if (id) {
- const int do_scene_obj = (GS(id->name) == ID_OB) &&
- (template->ptr.type == &RNA_SceneObjects);
- /* make copy */
- if (do_scene_obj) {
- Scene *scene = CTX_data_scene(C);
- ED_object_single_user(scene, (struct Object *)id);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
- }
- else {
- if (id) {
- id_single_user(C, id, &template->ptr, template->prop);
- }
- }
- }
- break;
- #if 0
- case UI_ID_AUTO_NAME:
- break;
- #endif
- }
- }
- static const char *template_id_browse_tip(StructRNA *type)
- {
- if (type) {
- switch (RNA_type_to_ID_code(type)) {
- case ID_SCE: return N_("Browse Scene to be linked");
- case ID_OB: return N_("Browse Object to be linked");
- case ID_ME: return N_("Browse Mesh Data to be linked");
- case ID_CU: return N_("Browse Curve Data to be linked");
- case ID_MB: return N_("Browse Metaball Data to be linked");
- case ID_MA: return N_("Browse Material to be linked");
- case ID_TE: return N_("Browse Texture to be linked");
- case ID_IM: return N_("Browse Image to be linked");
- case ID_LT: return N_("Browse Lattice Data to be linked");
- case ID_LA: return N_("Browse Lamp Data to be linked");
- case ID_CA: return N_("Browse Camera Data to be linked");
- case ID_WO: return N_("Browse World Settings to be linked");
- case ID_SCR: return N_("Choose Screen lay-out");
- case ID_TXT: return N_("Browse Text to be linked");
- case ID_SPK: return N_("Browse Speaker Data to be linked");
- case ID_SO: return N_("Browse Sound to be linked");
- case ID_AR: return N_("Browse Armature data to be linked");
- case ID_AC: return N_("Browse Action to be linked");
- case ID_NT: return N_("Browse Node Tree to be linked");
- case ID_BR: return N_("Browse Brush to be linked");
- case ID_PA: return N_("Browse Particle System to be linked");
- case ID_GD: return N_("Browse Grease Pencil Data to be linked");
- }
- }
- return N_("Browse ID data to be linked");
- }
- static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag, const char *newop, const char *openop, const char *unlinkop)
- {
- uiBut *but;
- uiBlock *block;
- PointerRNA idptr;
- // ListBase *lb; // UNUSED
- ID *id, *idfrom;
- int editable = RNA_property_editable(&template->ptr, template->prop);
- idptr = RNA_property_pointer_get(&template->ptr, template->prop);
- id = idptr.data;
- idfrom = template->ptr.id.data;
- // lb= template->idlb;
- block = uiLayoutGetBlock(layout);
- uiBlockBeginAlign(block);
- if (idptr.type)
- type = idptr.type;
- if (flag & UI_ID_PREVIEWS) {
- but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6,
- TIP_(template_id_browse_tip(type)));
- if (type) {
- but->icon = RNA_struct_ui_icon(type);
- if (id) but->icon = ui_id_icon_get(C, id, 1);
- uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
- }
- if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
-
- uiLayoutRow(layout, 1);
- template->preview = 1;
- }
- else if (flag & UI_ID_BROWSE) {
- but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y,
- TIP_(template_id_browse_tip(type)));
- if (type) {
- but->icon = RNA_struct_ui_icon(type);
- /* default dragging of icon for id browse buttons */
- uiButSetDragID(but, id);
- uiButSetFlag(but, UI_HAS_ICON | UI_ICON_LEFT);
- }
- if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- /* text button with name */
- if (id) {
- char name[UI_MAX_NAME_STR];
- const short user_alert = (id->us <= 0);
- //text_idbutton(id, name);
- name[0] = '\0';
- but = uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
- if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
- if (id->lib) {
- if (id->flag & LIB_INDIRECT) {
- but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Indirect library datablock, cannot change"));
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- else {
- but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Direct linked library datablock, click to make local"));
- if (!id_make_local(id, 1 /* test */) || (idfrom && idfrom->lib))
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL));
- }
- if (id->us > 1) {
- char numstr[32];
- BLI_snprintf(numstr, sizeof(numstr), "%d", id->us);
- but = uiDefBut(block, BUT, 0, numstr, 0, 0, UI_UNIT_X + ((id->us < 10) ? 0 : 10), UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Display number of users of this data (click to make a single-user copy)"));
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
- if (!id_copy(id, NULL, 1 /* test only */) || (idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
-
- if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
-
- if (id->lib == NULL && !(ELEM5(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB))) {
- uiDefButR(block, TOG, 0, "F", 0, 0, UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL);
- }
- }
-
- if (flag & UI_ID_ADD_NEW) {
- int w = id ? UI_UNIT_X : (flag & UI_ID_OPEN) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
-
- if (newop) {
- but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, (id) ? "" : IFACE_("New"), 0, 0, w, UI_UNIT_Y, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
- }
- else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : IFACE_("New"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
- }
- if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- if (flag & UI_ID_OPEN) {
- int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
-
- if (openop) {
- but = uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
- }
- else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
- }
- if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
-
- /* delete button */
- if (id && (flag & UI_ID_DELETE) && (RNA_property_flag(template->prop) & PROP_NEVER_UNLINK) == 0) {
- if (unlinkop) {
- but = uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
- /* so we can access the template from operators, font unlinking needs this */
- uiButSetNFunc(but, NULL, MEM_dupallocN(template), NULL);
- }
- else {
- but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Unlink datablock. Shift + Click to set users to zero, data will then not be saved"));
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
- if (RNA_property_flag(template->prop) & PROP_NEVER_NULL)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- if (idcode == ID_TE)
- uiTemplateTextureShow(layout, C, &template->ptr, template->prop);
-
- uiBlockEndAlign(block);
- }
- static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols)
- {
- TemplateID *template;
- PropertyRNA *prop;
- StructRNA *type;
- short idcode;
- prop = RNA_struct_find_property(ptr, propname);
- if (!prop || RNA_property_type(prop) != PROP_POINTER) {
- RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
- template = MEM_callocN(sizeof(TemplateID), "TemplateID");
- template->ptr = *ptr;
- template->prop = prop;
- template->prv_rows = prv_rows;
- template->prv_cols = prv_cols;
- if (newop)
- flag |= UI_ID_ADD_NEW;
- if (openop)
- flag |= UI_ID_OPEN;
- type = RNA_property_pointer_type(ptr, prop);
- idcode = RNA_type_to_ID_code(type);
- template->idlb = which_libbase(CTX_data_main(C), idcode);
-
- /* create UI elements for this template
- * - template_ID makes a copy of the template data and assigns it to the relevant buttons
- */
- if (template->idlb) {
- uiLayoutRow(layout, 1);
- template_ID(C, layout, template, type, idcode, flag, newop, openop, unlinkop);
- }
- MEM_freeN(template);
- }
- void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop)
- {
- ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, 0, 0);
- }
- void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop)
- {
- ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME, 0, 0);
- }
- void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int rows, int cols)
- {
- ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, rows, cols);
- }
- /************************ ID Chooser Template ***************************/
- /* This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use
- *
- * - propname: property identifier for property that ID-pointer gets stored to
- * - proptypename: property identifier for property used to determine the type of ID-pointer that can be used
- */
- void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename, const char *text)
- {
- PropertyRNA *propID, *propType;
- uiLayout *row;
-
- /* get properties... */
- propID = RNA_struct_find_property(ptr, propname);
- propType = RNA_struct_find_property(ptr, proptypename);
- if (!propID || RNA_property_type(propID) != PROP_POINTER) {
- RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
- if (!propType || RNA_property_type(propType) != PROP_ENUM) {
- RNA_warning("pointer-type property not found: %s.%s", RNA_struct_identifier(ptr->type), proptypename);
- return;
- }
-
- /* Start drawing UI Elements using standard defines */
- row = uiLayoutRow(layout, 1);
-
- /* Label - either use the provided text, or will become "ID-Block:" */
- if (text)
- uiItemL(row, text, ICON_NONE);
- else
- uiItemL(row, "ID-Block:", ICON_NONE);
-
- /* ID-Type Selector - just have a menu of icons */
- // FIXME: the icon-only setting doesn't work when we supply a blank name
- uiItemFullR(row, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
- /* ID-Block Selector - just use pointer widget... */
- uiItemFullR(row, ptr, propID, 0, 0, 0, "", ICON_NONE);
- }
- /********************* RNA Path Builder Template ********************/
- /* ---------- */
- /* This is creating/editing RNA-Paths
- *
- * - ptr: struct which holds the path property
- * - propname: property identifier for property that path gets stored to
- * - root_ptr: struct that path gets built from
- */
- void uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *UNUSED(root_ptr), const char *text)
- {
- PropertyRNA *propPath;
- uiLayout *row;
-
- /* check that properties are valid */
- propPath = RNA_struct_find_property(ptr, propname);
- if (!propPath || RNA_property_type(propPath) != PROP_STRING) {
- RNA_warning("path property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- /* Start drawing UI Elements using standard defines */
- row = uiLayoutRow(layout, 1);
-
- /* Path (existing string) Widget */
- uiItemR(row, ptr, propname, 0, text, ICON_RNA);
-
- // TODO: attach something to this to make allow searching of nested properties to 'build' the path
- }
- /************************ Modifier Template *************************/
- #define ERROR_LIBDATA_MESSAGE "Can't edit external libdata"
- #include <string.h>
- #include "DNA_object_force.h"
- #include "BKE_depsgraph.h"
- #include "BKE_modifier.h"
- #include "BKE_particle.h"
- #include "ED_util.h"
- #include "BLI_math.h"
- #include "BLI_listbase.h"
- #include "ED_object.h"
- static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v)
- {
- Scene *scene = CTX_data_scene(C);
- Object *ob = ob_v;
- ModifierData *md = md_v;
- int i, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 0);
- /* undo button operation */
- md->mode ^= eModifierMode_OnCage;
- for (i = 0, md = ob->modifiers.first; md; ++i, md = md->next) {
- if (md == md_v) {
- if (i >= cageIndex)
- md->mode ^= eModifierMode_OnCage;
- break;
- }
- }
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- }
- static void modifiers_convertToReal(bContext *C, void *ob_v, void *md_v)
- {
- Object *ob = ob_v;
- ModifierData *md = md_v;
- ModifierData *nmd = modifier_new(md->type);
- modifier_copyData(md, nmd);
- nmd->mode &= ~eModifierMode_Virtual;
- BLI_addhead(&ob->modifiers, nmd);
-
- modifier_unique_name(&ob->modifiers, nmd);
- ob->partype = PAROBJECT;
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- ED_undo_push(C, "Modifier convert to real");
- }
- static int modifier_can_delete(ModifierData *md)
- {
- /* fluid particle modifier can't be deleted here */
- if (md->type == eModifierType_ParticleSystem)
- if (((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID)
- return 0;
- return 1;
- }
- /* Check wheter Modifier is a simulation or not, this is used for switching to the physics/particles context tab */
- static int modifier_is_simulation(ModifierData *md)
- {
- /* Physic Tab */
- if (ELEM7(md->type, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim, eModifierType_Smoke,
- eModifierType_Softbody, eModifierType_Surface, eModifierType_DynamicPaint))
- {
- return 1;
- }
- /* Particle Tab */
- else if (md->type == eModifierType_ParticleSystem) {
- return 2;
- }
- else {
- return 0;
- }
- }
- static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
- ModifierData *md, int index, int cageIndex, int lastCageIndex)
- {
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- PointerRNA ptr;
- uiBut *but;
- uiBlock *block;
- uiLayout *box, *column, *row;
- uiLayout *result = NULL;
- int isVirtual = (md->mode & eModifierMode_Virtual);
- char str[128];
- /* create RNA pointer */
- RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
- column = uiLayoutColumn(layout, 1);
- uiLayoutSetContextPointer(column, "modifier", &ptr);
- /* rounded header ------------------------------------------------------------------- */
- box = uiLayoutBox(column);
-
- if (isVirtual) {
- row = uiLayoutRow(box, 0);
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
- block = uiLayoutGetBlock(row);
- /* VIRTUAL MODIFIER */
- // XXX this is not used now, since these cannot be accessed via RNA
- BLI_snprintf(str, sizeof(str), "%s parent deform", md->name);
- uiDefBut(block, LABEL, 0, str, 0, 0, 185, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name");
-
- but = uiDefBut(block, BUT, 0, IFACE_("Make Real"), 0, 0, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0,
- TIP_("Convert virtual modifier to a real modifier"));
- uiButSetFunc(but, modifiers_convertToReal, ob, md);
- }
- else {
- /* REAL MODIFIER */
- row = uiLayoutRow(box, 0);
- block = uiLayoutGetBlock(row);
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
- /* Open/Close ................................. */
- uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
-
- /* modifier-type icon */
- uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- /* modifier name */
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
-
- /* mode enabling buttons */
- uiBlockBeginAlign(block);
- /* Softbody not allowed in this situation, enforce! */
- if (((md->type != eModifierType_Softbody && md->type != eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) &&
- (md->type != eModifierType_Surface) )
- {
- uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
- uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
-
- if (mti->flags & eModifierTypeFlag_SupportsEditmode)
- uiItemR(row, &ptr, "show_in_editmode", 0, "", ICON_NONE);
- }
- if (ob->type == OB_MESH) {
- if (modifier_couldBeCage(scene, md) && (index <= lastCageIndex)) {
- /* -- convert to rna ? */
- but = uiDefIconButBitI(block, TOG, eModifierMode_OnCage, 0, ICON_MESH_DATA, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
- TIP_("Apply modifier to editing cage during Editmode"));
- if (index < cageIndex)
- uiButSetFlag(but, UI_BUT_DISABLED);
- uiButSetFunc(but, modifiers_setOnCage, ob, md);
- }
- else {
- uiBlockEndAlign(block);
- /* place holder button */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- but = uiDefIconBut(block, BUT, 0, ICON_NONE, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, NULL);
- uiButSetFlag(but, UI_BUT_DISABLED);
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- } /* tessellation point for curve-typed objects */
- else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
- /* some modifiers could work with pre-tessellated curves only */
- if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
- /* add disabled pre-tessellated button, so users could have
- * message for this modifiers */
- but = uiDefIconButBitI(block, TOG, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
- TIP_("This modifier could be applied on splines' points only"));
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- else if (mti->type != eModifierTypeType_Constructive) {
- /* constructive modifiers tessellates curve before applying */
- uiItemR(row, &ptr, "use_apply_on_spline", 0, "", ICON_NONE);
- }
- }
- uiBlockEndAlign(block);
-
- /* Up/Down + Delete ........................... */
- uiBlockBeginAlign(block);
- uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_modifier_move_up");
- uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_modifier_move_down");
- uiBlockEndAlign(block);
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
- // When Modifier is a simulation, show button to switch to context rather than the delete button.
- if (modifier_can_delete(md) && !modifier_is_simulation(md))
- uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove");
- if (modifier_is_simulation(md) == 1)
- uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PHYSICS");
- else if (modifier_is_simulation(md) == 2)
- uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PARTICLES");
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
-
- /* modifier settings (under the header) --------------------------------------------------- */
- if (!isVirtual && (md->mode & eModifierMode_Expanded)) {
- /* apply/convert/copy */
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, 0);
-
- if (!ELEM(md->type, eModifierType_Collision, eModifierType_Surface)) {
- /* only here obdata, the rest of modifiers is ob level */
- uiBlockSetButLock(block, object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
- if (md->type == eModifierType_ParticleSystem) {
- ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
-
- if (!(ob->mode & OB_MODE_PARTICLE_EDIT) && psys->pathcache) {
- if (ELEM(psys->part->ren_as, PART_DRAW_GR, PART_DRAW_OB))
- uiItemO(row, "Convert", ICON_NONE, "OBJECT_OT_duplicates_make_real");
- else if (psys->part->ren_as == PART_DRAW_PATH)
- uiItemO(row, "Convert", ICON_NONE, "OBJECT_OT_modifier_convert");
- }
- }
- else {
- uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
- uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA);
-
- if (modifier_sameTopology(md) && !modifier_nonGeometrical(md))
- uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0, "apply_as", MODIFIER_APPLY_SHAPE);
- }
-
- uiBlockClearButLock(block);
- uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
-
- if (!ELEM5(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem, eModifierType_Cloth, eModifierType_Smoke))
- uiItemO(row, IFACE_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy");
- }
-
- /* result is the layout block inside the box, that we return so that modifier settings can be drawn */
- result = uiLayoutColumn(box, 0);
- block = uiLayoutAbsoluteBlock(box);
- }
-
- /* error messages */
- if (md->error) {
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, 0);
- uiItemL(row, md->error, ICON_ERROR);
- }
-
- return result;
- }
- uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
- {
- Scene *scene = CTX_data_scene(C);
- Object *ob;
- ModifierData *md, *vmd;
- int i, lastCageIndex, cageIndex;
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
- ob = ptr->id.data;
- md = ptr->data;
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
-
- uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
-
- /* find modifier and draw it */
- cageIndex = modifiers_getCageIndex(scene, ob, &lastCageIndex, 0);
- // XXX virtual modifiers are not accesible for python
- vmd = modifiers_getVirtualModifierList(ob);
- for (i = 0; vmd; i++, vmd = vmd->next) {
- if (md == vmd)
- return draw_modifier(layout, scene, ob, md, i, cageIndex, lastCageIndex);
- else if (vmd->mode & eModifierMode_Virtual)
- i--;
- }
- return NULL;
- }
- /************************ Constraint Template *************************/
- #include "DNA_constraint_types.h"
- #include "BKE_action.h"
- #include "BKE_constraint.h"
- #define REDRAWIPO 1
- #define REDRAWNLA 2
- #define REDRAWBUTSOBJECT 3
- #define REDRAWACTION 4
- #define B_CONSTRAINT_TEST 5
- #define B_CONSTRAINT_CHANGETARGET 6
- #define REMAKEIPO 8
- #define B_DIFF 9
- static void do_constraint_panels(bContext *C, void *ob_pt, int event)
- {
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- Object *ob = (Object *)ob_pt;
- switch (event) {
- case B_CONSTRAINT_TEST:
- break; // no handling
- case B_CONSTRAINT_CHANGETARGET:
- if (ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels
- DAG_scene_sort(bmain, scene);
- break;
- default:
- break;
- }
- // note: RNA updates now call this, commenting else it gets called twice.
- // if there are problems because of this, then rna needs changed update functions.
- //
- // object_test_constraints(ob);
- // if (ob->pose) update_pose_constraint_flags(ob->pose);
-
- if (ob->type == OB_ARMATURE) DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
- else DAG_id_tag_update(&ob->id, OB_RECALC_OB);
- WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
- }
- static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
- {
- ED_object_constraint_set_active(ob_v, con_v);
- }
- /* draw panel showing settings for a constraint */
- static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
- {
- bPoseChannel *pchan = get_active_posechannel(ob);
- bConstraintTypeInfo *cti;
- uiBlock *block;
- uiLayout *result = NULL, *col, *box, *row;
- PointerRNA ptr;
- char typestr[32];
- short proxy_protected, xco = 0, yco = 0;
- // int rb_col; // UNUSED
- /* get constraint typeinfo */
- cti = constraint_get_typeinfo(con);
- if (cti == NULL) {
- /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
- BLI_strncpy(typestr, (con->type == CONSTRAINT_TYPE_NULL) ? "Null" : "Unknown", sizeof(typestr));
- }
- else
- BLI_strncpy(typestr, cti->name, sizeof(typestr));
-
- /* determine whether constraint is proxy protected or not */
- if (proxylocked_constraints_owner(ob, pchan))
- proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
- else
- proxy_protected = 0;
- /* unless button has own callback, it adds this callback to button */
- block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_constraint_panels, ob);
- uiBlockSetFunc(block, constraint_active_func, ob, con);
- RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
- col = uiLayoutColumn(layout, 1);
- uiLayoutSetContextPointer(col, "constraint", &ptr);
- box = uiLayoutBox(col);
- row = uiLayoutRow(box, 0);
- block = uiLayoutGetBlock(box);
- /* Draw constraint header */
- /* open/close */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiItemR(row, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- /* name */
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco + 10, yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
- if (con->flag & CONSTRAINT_DISABLE)
- uiLayoutSetRedAlert(row, 1);
-
- if (proxy_protected == 0) {
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
- }
- else
- uiItemL(row, con->name, ICON_NONE);
-
- uiLayoutSetRedAlert(row, 0);
-
- /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
- if (proxy_protected) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
-
- /* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 244, yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 262, yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else {
- short prev_proxylock, show_upbut, show_downbut;
-
- /* Up/Down buttons:
- * Proxy-constraints are not allowed to occur after local (non-proxy) constraints
- * as that poses problems when restoring them, so disable the "up" button where
- * it may cause this situation.
- *
- * Up/Down buttons should only be shown (or not greyed - todo) if they serve some purpose.
- */
- if (proxylocked_constraints_owner(ob, pchan)) {
- if (con->prev) {
- prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
- }
- else
- prev_proxylock = 0;
- }
- else
- prev_proxylock = 0;
-
- show_upbut = ((prev_proxylock == 0) && (con->prev));
- show_downbut = (con->next) ? 1 : 0;
-
- /* enabled */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiItemR(row, &ptr, "mute", 0, "", (con->flag & CONSTRAINT_OFF) ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF);
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
-
- /* up/down */
- if (show_upbut || show_downbut) {
- uiBlockBeginAlign(block);
- if (show_upbut)
- uiItemO(row, "", ICON_TRIA_UP, "CONSTRAINT_OT_move_up");
-
- if (show_downbut)
- uiItemO(row, "", ICON_TRIA_DOWN, "CONSTRAINT_OT_move_down");
- uiBlockEndAlign(block);
- }
-
- /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiItemO(row, "", ICON_X, "CONSTRAINT_OT_delete");
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- /* Set but-locks for protected settings (magic numbers are used here!) */
- if (proxy_protected)
- uiBlockSetButLock(block, 1, "Cannot edit Proxy-Protected Constraint");
- /* Draw constraint data */
- if ((con->flag & CONSTRAINT_EXPAND) == 0) {
- (yco) -= 21;
- }
- else {
- box = uiLayoutBox(col);
- block = uiLayoutAbsoluteBlock(box);
- result = box;
- }
- /* clear any locks set up for proxies/lib-linking */
- uiBlockClearButLock(block);
- return result;
- }
- uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
- {
- Object *ob;
- bConstraint *con;
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
- RNA_warning("Expected constraint on object");
- return NULL;
- }
- ob = ptr->id.data;
- con = ptr->data;
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected constraint on object");
- return NULL;
- }
-
- uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
- /* hrms, the temporal constraint should not draw! */
- if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
- bKinematicConstraint *data = con->data;
- if (data->flag & CONSTRAINT_IK_TEMP)
- return NULL;
- }
- return draw_constraint(layout, ob, con);
- }
- /************************* Preview Template ***************************/
- #include "DNA_lamp_types.h"
- #include "DNA_material_types.h"
- #include "DNA_world_types.h"
- #define B_MATPRV 1
- static void do_preview_buttons(bContext *C, void *arg, int event)
- {
- switch (event) {
- case B_MATPRV:
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, arg);
- break;
- }
- }
- void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, MTex *slot)
- {
- uiLayout *row, *col;
- uiBlock *block;
- Material *ma = NULL;
- Tex *tex = (Tex *)id;
- ID *pid, *pparent;
- short *pr_texture = NULL;
- PointerRNA material_ptr;
- PointerRNA texture_ptr;
- if (id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) {
- RNA_warning("Expected ID of type material, texture, lamp or world");
- return;
- }
- /* decide what to render */
- pid = id;
- pparent = NULL;
- if (id && (GS(id->name) == ID_TE)) {
- if (parent && (GS(parent->name) == ID_MA))
- pr_texture = &((Material *)parent)->pr_texture;
- else if (parent && (GS(parent->name) == ID_WO))
- pr_texture = &((World *)parent)->pr_texture;
- else if (parent && (GS(parent->name) == ID_LA))
- pr_texture = &((Lamp *)parent)->pr_texture;
- if (pr_texture) {
- if (*pr_texture == TEX_PR_OTHER)
- pid = parent;
- else if (*pr_texture == TEX_PR_BOTH)
- pparent = parent;
- }
- }
- /* layout */
- block = uiLayoutGetBlock(layout);
- row = uiLayoutRow(layout, 0);
- col = uiLayoutColumn(row, 0);
- uiLayoutSetKeepAspect(col, 1);
-
- /* add preview */
- uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, pid, 0.0, 0.0, 0, 0, "");
- uiBlockSetDrawExtraFunc(block, ED_preview_draw, pparent, slot);
- uiBlockSetHandleFunc(block, do_preview_buttons, NULL);
-
- /* add buttons */
- if (pid && show_buttons) {
- if (GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
- if (GS(pid->name) == ID_MA) ma = (Material *)pid;
- else ma = (Material *)pparent;
-
- /* Create RNA Pointer */
- RNA_pointer_create(id, &RNA_Material, ma, &material_ptr);
- col = uiLayoutColumn(row, 1);
- uiLayoutSetScaleX(col, 1.5);
- uiItemR(col, &material_ptr, "preview_render_type", UI_ITEM_R_EXPAND, "", ICON_NONE);
- }
- if (pr_texture) {
- /* Create RNA Pointer */
- RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
-
- uiLayoutRow(layout, 1);
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_TEXTURE, 0, 0, "");
- if (GS(parent->name) == ID_MA)
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- else if (GS(parent->name) == ID_LA)
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Lamp"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- else if (GS(parent->name) == ID_WO)
- uiDefButS(block, ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
-
- /* Alpha button for texture preview */
- if (*pr_texture != TEX_PR_OTHER) {
- row = uiLayoutRow(layout, 0);
- uiItemR(row, &texture_ptr, "use_preview_alpha", 0, NULL, ICON_NONE);
- }
- }
- }
- }
- /********************** ColorRamp Template **************************/
- typedef struct RNAUpdateCb {
- PointerRNA ptr;
- PropertyRNA *prop;
- } RNAUpdateCb;
- static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
- {
- RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
- /* we call update here on the pointer property, this way the
- * owner of the curve mapping can still define it's own update
- * and notifier, even if the CurveMapping struct is shared. */
- RNA_property_update(C, &cb->ptr, cb->prop);
- }
- #define B_BANDCOL 1
- static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
- {
- ColorBand *coba = coba_v;
- float pos = 0.5f;
- if (coba->tot > 1) {
- if (coba->cur > 0) pos = (coba->data[coba->cur - 1].pos + coba->data[coba->cur].pos) * 0.5f;
- else pos = (coba->data[coba->cur + 1].pos + coba->data[coba->cur].pos) * 0.5f;
- }
- if (colorband_element_add(coba, pos)) {
- rna_update_cb(C, cb_v, NULL);
- ED_undo_push(C, "Add colorband");
- }
- }
- static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
- {
- ColorBand *coba = coba_v;
- if (colorband_element_remove(coba, coba->cur)) {
- ED_undo_push(C, "Delete colorband");
- rna_update_cb(C, cb_v, NULL);
- }
- }
- static void colorband_flip_cb(bContext *C, void *cb_v, void *coba_v)
- {
- CBData data_tmp[MAXCOLORBAND];
- ColorBand *coba = coba_v;
- int a;
- for (a = 0; a < coba->tot; a++) {
- data_tmp[a] = coba->data[coba->tot - (a + 1)];
- }
- for (a = 0; a < coba->tot; a++) {
- data_tmp[a].pos = 1.0f - data_tmp[a].pos;
- coba->data[a] = data_tmp[a];
- }
- /* may as well flip the cur*/
- coba->cur = coba->tot - (coba->cur + 1);
- ED_undo_push(C, "Flip colorband");
- rna_update_cb(C, cb_v, NULL);
- }
- static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
- {
- uiBut *bt = bt_v;
- ColorBand *coba = coba_v;
- /* sneaky update here, we need to sort the colorband points to be in order,
- * however the RNA pointer then is wrong, so we update it */
- colorband_update_sort(coba);
- bt->rnapoin.data = coba->data + coba->cur;
- }
- /* offset aligns from bottom, standard width 300, height 115 */
- static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb)
- {
- uiBut *bt;
- uiLayout *row;
- const int line1_y = yoffs + 65 + UI_UNIT_Y + 2; /* 2 for some space between the buttons */
- const int line2_y = yoffs + 65;
- if (coba == NULL) return;
- bt = uiDefBut(block, BUT, 0, IFACE_("Add"), 0 + xoffs, line1_y, 40, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Add a new color stop to the colorband"));
- uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
- bt = uiDefBut(block, BUT, 0, IFACE_("Delete"), 45 + xoffs, line1_y, 45, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Delete the active position"));
- uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
- /* XXX, todo for later - convert to operator - campbell */
- bt = uiDefBut(block, BUT, 0, "F", 95 + xoffs, line1_y, 20, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Flip colorband"));
- uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
- uiDefButS(block, NUM, 0, "", 120 + xoffs, line1_y, 80, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)), 0, 0, TIP_("Choose active color stop"));
- bt = uiDefButS(block, MENU, 0, IFACE_("Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4"),
- 210 + xoffs, line1_y, 90, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0, TIP_("Set interpolation between color stops"));
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- uiBlockEndAlign(block);
- bt = uiDefBut(block, BUT_COLORBAND, 0, "", xoffs, line2_y, 300, UI_UNIT_Y, coba, 0, 0, 0, 0, "");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- if (coba->tot) {
- CBData *cbd = coba->data + coba->cur;
- /* better to use rna so we can animate them */
- PointerRNA ptr;
- RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
- row = uiLayoutRow(layout, 0);
- uiItemR(row, &ptr, "position", 0, "Pos", ICON_NONE);
- bt = block->buttons.last;
- uiButSetFunc(bt, colorband_update_cb, bt, coba);
- uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
- }
- }
- static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand *coba, rctf *butr, RNAUpdateCb *cb)
- {
- uiBut *bt;
- float unit = (butr->xmax - butr->xmin) / 14.0f;
- float xs = butr->xmin;
- uiBlockBeginAlign(block);
- bt = uiDefBut(block, BUT, 0, IFACE_("Add"), xs, butr->ymin + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Add a new color stop to the colorband"));
- uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
- bt = uiDefBut(block, BUT, 0, IFACE_("Delete"), xs + 2.0f * unit, butr->ymin + UI_UNIT_Y, 1.5f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Delete the active position"));
- uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
- bt = uiDefBut(block, BUT, 0, "F", xs + 3.5f * unit, butr->ymin + UI_UNIT_Y, 0.5f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Flip the color ramp"));
- uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
- uiBlockEndAlign(block);
- if (coba->tot) {
- CBData *cbd = coba->data + coba->cur;
- PointerRNA ptr;
- RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
- uiItemR(layout, &ptr, "color", 0, "", ICON_NONE);
- }
- bt = uiDefButS(block, MENU, 0, TIP_("Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4"),
- xs + 10.0f * unit, butr->ymin + UI_UNIT_Y, unit * 4, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0,
- TIP_("Set interpolation between color stops"));
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- bt = uiDefBut(block, BUT_COLORBAND, 0, "", xs, butr->ymin, butr->xmax - butr->xmin, UI_UNIT_Y, coba, 0, 0, 0, 0, "");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- uiBlockEndAlign(block);
- }
- static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, rctf *butr, int small, RNAUpdateCb *cb)
- {
- if (small)
- colorband_buttons_small(layout, block, coba, butr, cb);
- else
- colorband_buttons_large(layout, block, coba, 0, 0, cb);
- }
- void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, int expand)
- {
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- RNAUpdateCb *cb;
- uiBlock *block;
- rctf rect;
- if (!prop || RNA_property_type(prop) != PROP_POINTER)
- return;
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp))
- return;
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
- block = uiLayoutAbsoluteBlock(layout);
- colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
- MEM_freeN(cb);
- }
- /********************* Histogram Template ************************/
- void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
- {
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- RNAUpdateCb *cb;
- uiBlock *block;
- uiBut *bt;
- Histogram *hist;
- rctf rect;
-
- if (!prop || RNA_property_type(prop) != PROP_POINTER)
- return;
-
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Histogram))
- return;
-
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
-
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
-
- block = uiLayoutAbsoluteBlock(layout);
- //colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
- hist = (Histogram *)cptr.data;
- hist->height = (hist->height <= UI_UNIT_Y) ? UI_UNIT_Y : hist->height;
- bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, rect.xmax - rect.xmin, hist->height, hist, 0, 0, 0, 0, "");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- MEM_freeN(cb);
- }
- /********************* Waveform Template ************************/
- void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
- {
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- RNAUpdateCb *cb;
- uiBlock *block;
- uiBut *bt;
- Scopes *scopes;
- rctf rect;
-
- if (!prop || RNA_property_type(prop) != PROP_POINTER)
- return;
-
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes))
- return;
- scopes = (Scopes *)cptr.data;
-
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
-
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
-
- block = uiLayoutAbsoluteBlock(layout);
-
- scopes->wavefrm_height = (scopes->wavefrm_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->wavefrm_height;
- bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, rect.xmax - rect.xmin, scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
- (void)bt; // UNUSED
-
- MEM_freeN(cb);
- }
- /********************* Vectorscope Template ************************/
- void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propname)
- {
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- RNAUpdateCb *cb;
- uiBlock *block;
- uiBut *bt;
- Scopes *scopes;
- rctf rect;
-
- if (!prop || RNA_property_type(prop) != PROP_POINTER)
- return;
-
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes))
- return;
- scopes = (Scopes *)cptr.data;
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
-
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
-
- block = uiLayoutAbsoluteBlock(layout);
- scopes->vecscope_height = (scopes->vecscope_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->…
Large files files are truncated, but you can click here to view the full file