Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/interface/interface_utils.c')
-rw-r--r--source/blender/editors/interface/interface_utils.c1056
1 files changed, 589 insertions, 467 deletions
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 915793445db..9920d4f1fa5 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -51,109 +50,230 @@
#include "interface_intern.h"
-
/*************************** RNA Utilities ******************************/
-uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2)
+uiBut *uiDefAutoButR(uiBlock *block,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int index,
+ const char *name,
+ int icon,
+ int x1,
+ int y1,
+ int x2,
+ int y2)
{
- uiBut *but = NULL;
-
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- {
- if (RNA_property_array_check(prop) && index == -1) {
- return NULL;
- }
-
- if (icon && name && name[0] == '\0') {
- but = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else if (icon) {
- but = uiDefIconTextButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_CHECKBOX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- break;
- }
- case PROP_INT:
- case PROP_FLOAT:
- {
- if (RNA_property_array_check(prop) && index == -1) {
- if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
- but = uiDefButR_prop(block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
- }
- else {
- return NULL;
- }
- }
- else if (RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) {
- but = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
-
- if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
- UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
- }
- break;
- }
- case PROP_ENUM:
- if (icon && name && name[0] == '\0') {
- but = uiDefIconButR_prop(block, UI_BTYPE_MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else if (icon) {
- but = uiDefIconTextButR_prop(block, UI_BTYPE_MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- break;
- case PROP_STRING:
- if (icon && name && name[0] == '\0') {
- but = uiDefIconButR_prop(block, UI_BTYPE_TEXT, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else if (icon) {
- but = uiDefIconTextButR_prop(block, UI_BTYPE_TEXT, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
-
- if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
- /* TEXTEDIT_UPDATE is usually used for search buttons. For these we also want
- * the 'x' icon to clear search string, so setting VALUE_CLEAR flag, too. */
- UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE | UI_BUT_VALUE_CLEAR);
- }
- break;
- case PROP_POINTER:
- {
- if (icon == 0) {
- PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
- icon = RNA_struct_ui_icon(pptr.type ? pptr.type : RNA_property_pointer_type(ptr, prop));
- }
- if (icon == ICON_DOT) {
- icon = 0;
- }
-
- but = uiDefIconTextButR_prop(block, UI_BTYPE_SEARCH_MENU, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- break;
- }
- case PROP_COLLECTION:
- {
- char text[256];
- BLI_snprintf(text, sizeof(text), IFACE_("%d items"), RNA_property_collection_length(ptr, prop));
- but = uiDefBut(block, UI_BTYPE_LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- break;
- }
- default:
- but = NULL;
- break;
- }
-
- return but;
+ uiBut *but = NULL;
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN: {
+ if (RNA_property_array_check(prop) && index == -1) {
+ return NULL;
+ }
+
+ if (icon && name && name[0] == '\0') {
+ but = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ icon,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else if (icon) {
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ icon,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(block,
+ UI_BTYPE_CHECKBOX,
+ 0,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ break;
+ }
+ case PROP_INT:
+ case PROP_FLOAT: {
+ if (RNA_property_array_check(prop) && index == -1) {
+ if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
+ }
+ else {
+ return NULL;
+ }
+ }
+ else if (RNA_property_subtype(prop) == PROP_PERCENTAGE ||
+ RNA_property_subtype(prop) == PROP_FACTOR) {
+ but = uiDefButR_prop(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+
+ if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+ UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
+ }
+ break;
+ }
+ case PROP_ENUM:
+ if (icon && name && name[0] == '\0') {
+ but = uiDefIconButR_prop(
+ block, UI_BTYPE_MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+ else if (icon) {
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_MENU,
+ 0,
+ icon,
+ NULL,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+ break;
+ case PROP_STRING:
+ if (icon && name && name[0] == '\0') {
+ but = uiDefIconButR_prop(
+ block, UI_BTYPE_TEXT, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+ else if (icon) {
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_TEXT,
+ 0,
+ icon,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+
+ if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+ /* TEXTEDIT_UPDATE is usually used for search buttons. For these we also want
+ * the 'x' icon to clear search string, so setting VALUE_CLEAR flag, too. */
+ UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE | UI_BUT_VALUE_CLEAR);
+ }
+ break;
+ case PROP_POINTER: {
+ if (icon == 0) {
+ PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
+ icon = RNA_struct_ui_icon(pptr.type ? pptr.type : RNA_property_pointer_type(ptr, prop));
+ }
+ if (icon == ICON_DOT) {
+ icon = 0;
+ }
+
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_SEARCH_MENU,
+ 0,
+ icon,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ break;
+ }
+ case PROP_COLLECTION: {
+ char text[256];
+ BLI_snprintf(
+ text, sizeof(text), IFACE_("%d items"), RNA_property_collection_length(ptr, prop));
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ break;
+ }
+ default:
+ but = NULL;
+ break;
+ }
+
+ return but;
}
/**
@@ -162,225 +282,227 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
*
* \param prop_activate_init: Property to activate on initial popup (#UI_BUT_ACTIVATE_ON_INIT).
*/
-eAutoPropButsReturn uiDefAutoButsRNA(
- uiLayout *layout, PointerRNA *ptr,
- bool (*check_prop)(PointerRNA *ptr, PropertyRNA *prop, void *user_data), void *user_data,
- PropertyRNA *prop_activate_init,
- const eButLabelAlign label_align, const bool compact)
+eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
+ PointerRNA *ptr,
+ bool (*check_prop)(PointerRNA *ptr,
+ PropertyRNA *prop,
+ void *user_data),
+ void *user_data,
+ PropertyRNA *prop_activate_init,
+ const eButLabelAlign label_align,
+ const bool compact)
{
- eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED;
- uiLayout *split, *col;
- const char *name;
-
- RNA_STRUCT_BEGIN (ptr, prop)
- {
- const int flag = RNA_property_flag(prop);
-
- if (flag & PROP_HIDDEN) {
- continue;
- }
- if (check_prop && check_prop(ptr, prop, user_data) == 0) {
- return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
- continue;
- }
-
- const PropertyType type = RNA_property_type(prop);
- switch (label_align) {
- case UI_BUT_LABEL_ALIGN_COLUMN:
- case UI_BUT_LABEL_ALIGN_SPLIT_COLUMN:
- {
- const bool is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));
-
- name = RNA_property_ui_name(prop);
-
- if (label_align == UI_BUT_LABEL_ALIGN_COLUMN) {
- col = uiLayoutColumn(layout, true);
-
- if (!is_boolean) {
- uiItemL(col, name, ICON_NONE);
- }
- }
- else {
- BLI_assert(label_align == UI_BUT_LABEL_ALIGN_SPLIT_COLUMN);
- split = uiLayoutSplit(layout, 0.5f, false);
-
- col = uiLayoutColumn(split, false);
- uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
- col = uiLayoutColumn(split, false);
- }
-
- /* May need to add more cases here.
- * don't override enum flag names */
-
- /* name is shown above, empty name for button below */
- name = (flag & PROP_ENUM_FLAG || is_boolean) ? NULL : "";
-
- break;
- }
- case UI_BUT_LABEL_ALIGN_NONE:
- default:
- col = layout;
- name = NULL; /* no smart label alignment, show default name with button */
- break;
- }
-
- /* Only buttons that can be edited as text. */
- const bool use_activate_init = (
- (prop == prop_activate_init) &&
- (ELEM(type, PROP_STRING, PROP_INT, PROP_FLOAT)));
-
- if (use_activate_init) {
- uiLayoutSetActivateInit(col, true);
- }
-
- uiItemFullR(col, ptr, prop, -1, 0, compact ? UI_ITEM_R_COMPACT : 0, name, ICON_NONE);
- return_info &= ~UI_PROP_BUTS_NONE_ADDED;
-
- if (use_activate_init) {
- uiLayoutSetActivateInit(col, false);
- }
-
- }
- RNA_STRUCT_END;
-
- return return_info;
+ eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED;
+ uiLayout *split, *col;
+ const char *name;
+
+ RNA_STRUCT_BEGIN (ptr, prop) {
+ const int flag = RNA_property_flag(prop);
+
+ if (flag & PROP_HIDDEN) {
+ continue;
+ }
+ if (check_prop && check_prop(ptr, prop, user_data) == 0) {
+ return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
+ continue;
+ }
+
+ const PropertyType type = RNA_property_type(prop);
+ switch (label_align) {
+ case UI_BUT_LABEL_ALIGN_COLUMN:
+ case UI_BUT_LABEL_ALIGN_SPLIT_COLUMN: {
+ const bool is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));
+
+ name = RNA_property_ui_name(prop);
+
+ if (label_align == UI_BUT_LABEL_ALIGN_COLUMN) {
+ col = uiLayoutColumn(layout, true);
+
+ if (!is_boolean) {
+ uiItemL(col, name, ICON_NONE);
+ }
+ }
+ else {
+ BLI_assert(label_align == UI_BUT_LABEL_ALIGN_SPLIT_COLUMN);
+ split = uiLayoutSplit(layout, 0.5f, false);
+
+ col = uiLayoutColumn(split, false);
+ uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
+ col = uiLayoutColumn(split, false);
+ }
+
+ /* May need to add more cases here.
+ * don't override enum flag names */
+
+ /* name is shown above, empty name for button below */
+ name = (flag & PROP_ENUM_FLAG || is_boolean) ? NULL : "";
+
+ break;
+ }
+ case UI_BUT_LABEL_ALIGN_NONE:
+ default:
+ col = layout;
+ name = NULL; /* no smart label alignment, show default name with button */
+ break;
+ }
+
+ /* Only buttons that can be edited as text. */
+ const bool use_activate_init = ((prop == prop_activate_init) &&
+ (ELEM(type, PROP_STRING, PROP_INT, PROP_FLOAT)));
+
+ if (use_activate_init) {
+ uiLayoutSetActivateInit(col, true);
+ }
+
+ uiItemFullR(col, ptr, prop, -1, 0, compact ? UI_ITEM_R_COMPACT : 0, name, ICON_NONE);
+ return_info &= ~UI_PROP_BUTS_NONE_ADDED;
+
+ if (use_activate_init) {
+ uiLayoutSetActivateInit(col, false);
+ }
+ }
+ RNA_STRUCT_END;
+
+ return return_info;
}
/* *** RNA collection search menu *** */
typedef struct CollItemSearch {
- struct CollItemSearch *next, *prev;
- void *data;
- char *name;
- int index;
- int iconid;
+ struct CollItemSearch *next, *prev;
+ void *data;
+ char *name;
+ int index;
+ int iconid;
} CollItemSearch;
static int sort_search_items_list(const void *a, const void *b)
{
- const CollItemSearch *cis1 = a;
- const CollItemSearch *cis2 = b;
-
- if (BLI_strcasecmp(cis1->name, cis2->name) > 0) {
- return 1;
- }
- else {
- return 0;
- }
+ const CollItemSearch *cis1 = a;
+ const CollItemSearch *cis2 = b;
+
+ if (BLI_strcasecmp(cis1->name, cis2->name) > 0) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
-void ui_rna_collection_search_cb(const struct bContext *C, void *arg, const char *str, uiSearchItems *items)
+void ui_rna_collection_search_cb(const struct bContext *C,
+ void *arg,
+ const char *str,
+ uiSearchItems *items)
{
- uiRNACollectionSearch *data = arg;
- char *name;
- int i = 0, iconid = 0, flag = RNA_property_flag(data->target_prop);
- ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
- CollItemSearch *cis;
- const bool skip_filter = (data->but_changed && !(*data->but_changed));
-
- /* build a temporary list of relevant items first */
- RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop)
- {
-
- if (flag & PROP_ID_SELF_CHECK) {
- if (itemptr.data == data->target_ptr.id.data) {
- continue;
- }
- }
-
- /* use filter */
- if (RNA_property_type(data->target_prop) == PROP_POINTER) {
- if (RNA_property_pointer_poll(&data->target_ptr, data->target_prop, &itemptr) == 0) {
- continue;
- }
- }
-
- name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
- iconid = 0;
- if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
- iconid = ui_id_icon_get(C, itemptr.data, false);
- }
-
- if (name) {
- if (skip_filter || BLI_strcasestr(name, str)) {
- cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
- cis->data = itemptr.data;
- cis->name = MEM_dupallocN(name);
- cis->index = i;
- cis->iconid = iconid;
- BLI_addtail(items_list, cis);
- }
- MEM_freeN(name);
- }
-
- i++;
- }
- RNA_PROP_END;
-
- BLI_listbase_sort(items_list, sort_search_items_list);
-
- /* add search items from temporary list */
- for (cis = items_list->first; cis; cis = cis->next) {
- if (UI_search_item_add(items, cis->name, cis->data, cis->iconid) == false) {
- break;
- }
- }
-
- for (cis = items_list->first; cis; cis = cis->next) {
- MEM_freeN(cis->name);
- }
- BLI_freelistN(items_list);
- MEM_freeN(items_list);
+ uiRNACollectionSearch *data = arg;
+ char *name;
+ int i = 0, iconid = 0, flag = RNA_property_flag(data->target_prop);
+ ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
+ CollItemSearch *cis;
+ const bool skip_filter = (data->but_changed && !(*data->but_changed));
+
+ /* build a temporary list of relevant items first */
+ RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop) {
+
+ if (flag & PROP_ID_SELF_CHECK) {
+ if (itemptr.data == data->target_ptr.id.data) {
+ continue;
+ }
+ }
+
+ /* use filter */
+ if (RNA_property_type(data->target_prop) == PROP_POINTER) {
+ if (RNA_property_pointer_poll(&data->target_ptr, data->target_prop, &itemptr) == 0) {
+ continue;
+ }
+ }
+
+ name = RNA_struct_name_get_alloc(
+ &itemptr, NULL, 0, NULL); /* could use the string length here */
+ iconid = 0;
+ if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
+ iconid = ui_id_icon_get(C, itemptr.data, false);
+ }
+
+ if (name) {
+ if (skip_filter || BLI_strcasestr(name, str)) {
+ cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
+ cis->data = itemptr.data;
+ cis->name = MEM_dupallocN(name);
+ cis->index = i;
+ cis->iconid = iconid;
+ BLI_addtail(items_list, cis);
+ }
+ MEM_freeN(name);
+ }
+
+ i++;
+ }
+ RNA_PROP_END;
+
+ BLI_listbase_sort(items_list, sort_search_items_list);
+
+ /* add search items from temporary list */
+ for (cis = items_list->first; cis; cis = cis->next) {
+ if (UI_search_item_add(items, cis->name, cis->data, cis->iconid) == false) {
+ break;
+ }
+ }
+
+ for (cis = items_list->first; cis; cis = cis->next) {
+ MEM_freeN(cis->name);
+ }
+ BLI_freelistN(items_list);
+ MEM_freeN(items_list);
}
-
/***************************** ID Utilities *******************************/
int UI_icon_from_id(ID *id)
{
- Object *ob;
- PointerRNA ptr;
- short idcode;
+ Object *ob;
+ PointerRNA ptr;
+ short idcode;
- if (id == NULL) {
- return ICON_NONE;
- }
+ if (id == NULL) {
+ return ICON_NONE;
+ }
- idcode = GS(id->name);
+ idcode = GS(id->name);
- /* exception for objects */
- if (idcode == ID_OB) {
- ob = (Object *)id;
+ /* exception for objects */
+ if (idcode == ID_OB) {
+ ob = (Object *)id;
- if (ob->type == OB_EMPTY) {
- return ICON_EMPTY_DATA;
- }
- else {
- return UI_icon_from_id(ob->data);
- }
- }
+ if (ob->type == OB_EMPTY) {
+ return ICON_EMPTY_DATA;
+ }
+ else {
+ return UI_icon_from_id(ob->data);
+ }
+ }
- /* otherwise get it through RNA, creating the pointer
- * will set the right type, also with subclassing */
- RNA_id_pointer_create(id, &ptr);
+ /* otherwise get it through RNA, creating the pointer
+ * will set the right type, also with subclassing */
+ RNA_id_pointer_create(id, &ptr);
- return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE;
+ return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE;
}
/* see: report_type_str */
int UI_icon_from_report_type(int type)
{
- if (type & RPT_ERROR_ALL) {
- return ICON_ERROR;
- }
- else if (type & RPT_WARNING_ALL) {
- return ICON_ERROR;
- }
- else if (type & RPT_INFO_ALL) {
- return ICON_INFO;
- }
- else {
- return ICON_NONE;
- }
+ if (type & RPT_ERROR_ALL) {
+ return ICON_ERROR;
+ }
+ else if (type & RPT_WARNING_ALL) {
+ return ICON_ERROR;
+ }
+ else if (type & RPT_INFO_ALL) {
+ return ICON_INFO;
+ }
+ else {
+ return ICON_NONE;
+ }
}
/********************************** Misc **************************************/
@@ -390,84 +512,86 @@ int UI_icon_from_report_type(int type)
*/
int UI_calc_float_precision(int prec, double value)
{
- static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6};
- static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */
-
- BLI_assert(prec <= UI_PRECISION_FLOAT_MAX);
- BLI_assert(fabs(pow10_neg[prec] - pow(10, -prec)) < 1e-16);
-
- /* check on the number of decimal places need to display the number, this is so 0.00001 is not displayed as 0.00,
- * _but_, this is only for small values si 10.0001 will not get the same treatment.
- */
- value = ABS(value);
- if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
- int value_i = (int)((value * max_pow) + 0.5);
- if (value_i != 0) {
- const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
- int test_prec;
- int prec_min = -1;
- int dec_flag = 0;
- int i = UI_PRECISION_FLOAT_MAX;
- while (i && value_i) {
- if (value_i % 10) {
- dec_flag |= 1 << i;
- prec_min = i;
- }
- value_i /= 10;
- i--;
- }
-
- /* even though its a small value, if the second last digit is not 0, use it */
- test_prec = prec_min;
-
- dec_flag = (dec_flag >> (prec_min + 1)) & ((1 << prec_span) - 1);
-
- while (dec_flag) {
- test_prec++;
- dec_flag = dec_flag >> 1;
- }
-
- if (test_prec > prec) {
- prec = test_prec;
- }
- }
- }
-
- CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
-
- return prec;
+ static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {
+ 1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6};
+ static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */
+
+ BLI_assert(prec <= UI_PRECISION_FLOAT_MAX);
+ BLI_assert(fabs(pow10_neg[prec] - pow(10, -prec)) < 1e-16);
+
+ /* check on the number of decimal places need to display the number, this is so 0.00001 is not displayed as 0.00,
+ * _but_, this is only for small values si 10.0001 will not get the same treatment.
+ */
+ value = ABS(value);
+ if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
+ int value_i = (int)((value * max_pow) + 0.5);
+ if (value_i != 0) {
+ const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
+ int test_prec;
+ int prec_min = -1;
+ int dec_flag = 0;
+ int i = UI_PRECISION_FLOAT_MAX;
+ while (i && value_i) {
+ if (value_i % 10) {
+ dec_flag |= 1 << i;
+ prec_min = i;
+ }
+ value_i /= 10;
+ i--;
+ }
+
+ /* even though its a small value, if the second last digit is not 0, use it */
+ test_prec = prec_min;
+
+ dec_flag = (dec_flag >> (prec_min + 1)) & ((1 << prec_span) - 1);
+
+ while (dec_flag) {
+ test_prec++;
+ dec_flag = dec_flag >> 1;
+ }
+
+ if (test_prec > prec) {
+ prec = test_prec;
+ }
+ }
+ }
+
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+
+ return prec;
}
bool UI_but_online_manual_id(const uiBut *but, char *r_str, size_t maxlength)
{
- if (but->rnapoin.id.data && but->rnapoin.data && but->rnaprop) {
- BLI_snprintf(
- r_str, maxlength, "%s.%s", RNA_struct_identifier(but->rnapoin.type),
- RNA_property_identifier(but->rnaprop));
- return true;
- }
- else if (but->optype) {
- WM_operator_py_idname(r_str, but->optype->idname);
- return true;
- }
-
- *r_str = '\0';
- return false;
+ if (but->rnapoin.id.data && but->rnapoin.data && but->rnaprop) {
+ BLI_snprintf(r_str,
+ maxlength,
+ "%s.%s",
+ RNA_struct_identifier(but->rnapoin.type),
+ RNA_property_identifier(but->rnaprop));
+ return true;
+ }
+ else if (but->optype) {
+ WM_operator_py_idname(r_str, but->optype->idname);
+ return true;
+ }
+
+ *r_str = '\0';
+ return false;
}
bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str, size_t maxlength)
{
- uiBut *but = UI_context_active_but_get(C);
+ uiBut *but = UI_context_active_but_get(C);
- if (but) {
- return UI_but_online_manual_id(but, r_str, maxlength);
- }
+ if (but) {
+ return UI_but_online_manual_id(but, r_str, maxlength);
+ }
- *r_str = '\0';
- return false;
+ *r_str = '\0';
+ return false;
}
-
/* -------------------------------------------------------------------- */
/* Modal Button Store API */
@@ -481,14 +605,14 @@ bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str,
* \{ */
struct uiButStore {
- struct uiButStore *next, *prev;
- uiBlock *block;
- ListBase items;
+ struct uiButStore *next, *prev;
+ uiBlock *block;
+ ListBase items;
};
struct uiButStoreElem {
- struct uiButStoreElem *next, *prev;
- uiBut **but_p;
+ struct uiButStoreElem *next, *prev;
+ uiBut **but_p;
};
/**
@@ -496,78 +620,77 @@ struct uiButStoreElem {
*/
uiButStore *UI_butstore_create(uiBlock *block)
{
- uiButStore *bs_handle = MEM_callocN(sizeof(uiButStore), __func__);
+ uiButStore *bs_handle = MEM_callocN(sizeof(uiButStore), __func__);
- bs_handle->block = block;
- BLI_addtail(&block->butstore, bs_handle);
+ bs_handle->block = block;
+ BLI_addtail(&block->butstore, bs_handle);
- return bs_handle;
+ return bs_handle;
}
void UI_butstore_free(uiBlock *block, uiButStore *bs_handle)
{
- /* Workaround for button store being moved into new block,
- * which then can't use the previous buttons state ('ui_but_update_from_old_block' fails to find a match),
- * keeping the active button in the old block holding a reference to the button-state in the new block: see T49034.
- *
- * Ideally we would manage moving the 'uiButStore', keeping a correct state.
- * All things considered this is the most straightforward fix - Campbell.
- */
- if (block != bs_handle->block && bs_handle->block != NULL) {
- block = bs_handle->block;
- }
-
- BLI_freelistN(&bs_handle->items);
- BLI_remlink(&block->butstore, bs_handle);
-
- MEM_freeN(bs_handle);
+ /* Workaround for button store being moved into new block,
+ * which then can't use the previous buttons state ('ui_but_update_from_old_block' fails to find a match),
+ * keeping the active button in the old block holding a reference to the button-state in the new block: see T49034.
+ *
+ * Ideally we would manage moving the 'uiButStore', keeping a correct state.
+ * All things considered this is the most straightforward fix - Campbell.
+ */
+ if (block != bs_handle->block && bs_handle->block != NULL) {
+ block = bs_handle->block;
+ }
+
+ BLI_freelistN(&bs_handle->items);
+ BLI_remlink(&block->butstore, bs_handle);
+
+ MEM_freeN(bs_handle);
}
bool UI_butstore_is_valid(uiButStore *bs)
{
- return (bs->block != NULL);
+ return (bs->block != NULL);
}
bool UI_butstore_is_registered(uiBlock *block, uiBut *but)
{
- uiButStore *bs_handle;
+ uiButStore *bs_handle;
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+ uiButStoreElem *bs_elem;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- if (*bs_elem->but_p == but) {
- return true;
- }
- }
- }
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ if (*bs_elem->but_p == but) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p)
{
- uiButStoreElem *bs_elem = MEM_callocN(sizeof(uiButStoreElem), __func__);
- BLI_assert(*but_p);
- bs_elem->but_p = but_p;
-
- BLI_addtail(&bs_handle->items, bs_elem);
+ uiButStoreElem *bs_elem = MEM_callocN(sizeof(uiButStoreElem), __func__);
+ BLI_assert(*but_p);
+ bs_elem->but_p = but_p;
+ BLI_addtail(&bs_handle->items, bs_elem);
}
void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
{
- uiButStoreElem *bs_elem, *bs_elem_next;
+ uiButStoreElem *bs_elem, *bs_elem_next;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) {
- bs_elem_next = bs_elem->next;
- if (bs_elem->but_p == but_p) {
- BLI_remlink(&bs_handle->items, bs_elem);
- MEM_freeN(bs_elem);
- }
- }
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) {
+ bs_elem_next = bs_elem->next;
+ if (bs_elem->but_p == but_p) {
+ BLI_remlink(&bs_handle->items, bs_elem);
+ MEM_freeN(bs_elem);
+ }
+ }
- BLI_assert(0);
+ BLI_assert(0);
}
/**
@@ -575,20 +698,20 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
*/
bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src)
{
- uiButStore *bs_handle;
- bool found = false;
-
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- if (*bs_elem->but_p == but_src) {
- *bs_elem->but_p = but_dst;
- found = true;
- }
- }
- }
-
- return found;
+ uiButStore *bs_handle;
+ bool found = false;
+
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+ uiButStoreElem *bs_elem;
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ if (*bs_elem->but_p == but_src) {
+ *bs_elem->but_p = but_dst;
+ found = true;
+ }
+ }
+ }
+
+ return found;
}
/**
@@ -596,17 +719,17 @@ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *bu
*/
void UI_butstore_clear(uiBlock *block)
{
- uiButStore *bs_handle;
+ uiButStore *bs_handle;
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+ uiButStoreElem *bs_elem;
- bs_handle->block = NULL;
+ bs_handle->block = NULL;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- *bs_elem->but_p = NULL;
- }
- }
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ *bs_elem->but_p = NULL;
+ }
+ }
}
/**
@@ -614,45 +737,44 @@ void UI_butstore_clear(uiBlock *block)
*/
void UI_butstore_update(uiBlock *block)
{
- uiButStore *bs_handle;
-
- /* move this list to the new block */
- if (block->oldblock) {
- if (block->oldblock->butstore.first) {
- block->butstore = block->oldblock->butstore;
- BLI_listbase_clear(&block->oldblock->butstore);
- }
- }
-
- if (LIKELY(block->butstore.first == NULL)) {
- return;
- }
-
- /* warning, loop-in-loop, in practice we only store <10 buttons at a time,
- * so this isn't going to be a problem, if that changes old-new mapping can be cached first */
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
-
- BLI_assert((bs_handle->block == NULL) ||
- (bs_handle->block == block) ||
- (block->oldblock && block->oldblock == bs_handle->block));
-
- if (bs_handle->block == block->oldblock) {
- uiButStoreElem *bs_elem;
-
- bs_handle->block = block;
-
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- if (*bs_elem->but_p) {
- uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
-
- /* can be NULL if the buttons removed,
- * note: we could allow passing in a callback when buttons are removed
- * so the caller can cleanup */
- *bs_elem->but_p = but_new;
- }
- }
- }
- }
+ uiButStore *bs_handle;
+
+ /* move this list to the new block */
+ if (block->oldblock) {
+ if (block->oldblock->butstore.first) {
+ block->butstore = block->oldblock->butstore;
+ BLI_listbase_clear(&block->oldblock->butstore);
+ }
+ }
+
+ if (LIKELY(block->butstore.first == NULL)) {
+ return;
+ }
+
+ /* warning, loop-in-loop, in practice we only store <10 buttons at a time,
+ * so this isn't going to be a problem, if that changes old-new mapping can be cached first */
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+
+ BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) ||
+ (block->oldblock && block->oldblock == bs_handle->block));
+
+ if (bs_handle->block == block->oldblock) {
+ uiButStoreElem *bs_elem;
+
+ bs_handle->block = block;
+
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ if (*bs_elem->but_p) {
+ uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
+
+ /* can be NULL if the buttons removed,
+ * note: we could allow passing in a callback when buttons are removed
+ * so the caller can cleanup */
+ *bs_elem->but_p = but_new;
+ }
+ }
+ }
+ }
}
/** \} */