diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-02-11 02:06:03 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-02-11 02:07:09 +0300 |
commit | 4f1e3875884506c017e03469658e9e7dadeeb500 (patch) | |
tree | ea3f5325a349ba3c749b7b5df6d0023329b070f4 | |
parent | d18993d4e457b195b2ebfc910dbaf14a023e1ec8 (diff) |
UI: add optional tip callback to uiBut, and use it for per-item tooltips in UIList.
When defined, uiBut->tip_func is called when button's tip is generated. This allows
for advanced, dynamic generation of tooltips.
For now, only used by UIList, which can now optionaly use a given string property
of each item for its tooltip.
Thanks to Campbell for the reviews!
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 8 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 19 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 6 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 27 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_buttons.c | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui_api.c | 2 | ||||
-rw-r--r-- | source/blenderplayer/bad_level_call_stubs/stubs.c | 2 |
8 files changed, 62 insertions, 10 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 590ab1d694d..b1bb48b58ed 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -348,6 +348,9 @@ typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origs typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2); typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items); +/* Must return allocated string. */ +typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip); + typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event); /* Menu Callbacks */ @@ -678,6 +681,8 @@ void UI_but_func_drawextra_set( void (*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect), void *arg1, void *arg2); +void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN); + bool UI_textbutton_activate_rna(const struct bContext *C, struct ARegion *ar, const void *rna_poin_data, const char *rna_prop_id); bool UI_textbutton_activate_but(const struct bContext *C, uiBut *but); @@ -907,7 +912,8 @@ void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float *color); #define UI_UL_DEFAULT_CLASS_NAME "UI_UL_list" void uiTemplateList(uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id, struct PointerRNA *dataptr, const char *propname, struct PointerRNA *active_dataptr, - const char *active_propname, int rows, int maxrows, int layout_type, int columns); + const char *active_propname, const char *item_dyntip_propname, + int rows, int maxrows, int layout_type, int columns); void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); void uiTemplateTextureUser(uiLayout *layout, struct bContext *C); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 8fa604d57cb..bad09a7c441 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -716,6 +716,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu if (oldbut->poin != (char *)oldbut) { SWAP(char *, oldbut->poin, but->poin); SWAP(void *, oldbut->func_argN, but->func_argN); + SWAP(void *, oldbut->tip_argN, but->tip_argN); } oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); @@ -2440,6 +2441,10 @@ static void ui_but_free(const bContext *C, uiBut *but) MEM_freeN(but->func_argN); } + if (but->tip_argN) { + MEM_freeN(but->tip_argN); + } + if (but->active) { /* XXX solve later, buttons should be free-able without context ideally, * however they may have open tooltips or popup windows, which need to @@ -4113,6 +4118,15 @@ void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg) but->autofunc_arg = arg; } +void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN) +{ + but->tip_func = func; + if (but->tip_argN) { + MEM_freeN(but->tip_argN); + } + but->tip_argN = argN; +} + uiBut *uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) { uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); @@ -4383,7 +4397,10 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } } else if (type == BUT_GET_TIP) { - if (but->tip && but->tip[0]) + if (but->tip_func) { + tmp = but->tip_func(C, but->tip_argN, but->tip); + } + else if (but->tip && but->tip[0]) tmp = BLI_strdup(but->tip); else type = BUT_GET_RNA_TIP; /* Fail-safe solution... */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 458e268170f..03816a255ad 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -254,7 +254,11 @@ struct uiBut { uiLink *link; short linkto[2]; /* region relative coords */ - const char *tip, *lockstr; + const char *tip; + uiButToolTipFunc tip_func; + void *tip_argN; + + const char *lockstr; BIFIconID icon; bool lock; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 5ac991cbd94..b3c31a1a644 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2833,9 +2833,27 @@ static void uilist_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUSE } } +static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname) +{ + if (propname && propname[0] && itemptr && itemptr->data) { + PropertyRNA *prop = RNA_struct_find_property(itemptr, propname); + + if (prop && (RNA_property_type(prop) == PROP_STRING)) { + return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL); + } + } + return NULL; +} + +static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip) +{ + char *dyn_tooltip = argN; + return BLI_sprintfN("%s - %s", tip, dyn_tooltip); +} + void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, - int rows, int maxrows, int layout_type, int columns) + const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns) { uiListType *ui_list_type; uiList *ui_list = NULL; @@ -3049,6 +3067,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co /* create list items */ for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) { PointerRNA *itemptr = &items_ptr[i].item; + void *dyntip_data; int org_i = items_ptr[i].org_idx; int flt_flag = items_ptr[i].flt_flag; subblock = uiLayoutGetBlock(col); @@ -3061,7 +3080,11 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co sub = uiLayoutRow(overlap, false); but = uiDefButR_prop(subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, - active_dataptr, activeprop, 0, 0, org_i, 0, 0, TIP_("Double click to rename")); + active_dataptr, activeprop, 0, 0, org_i, 0, 0, + TIP_("Double click to rename")); + if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) { + UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data); + } sub = uiLayoutRow(overlap, false); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 2089dced7e3..6fa164a483f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1747,13 +1747,13 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi /* using different collection properties if multilayer format is enabled */ if (multilayer) { uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "layer_slots", ptr, "active_input_index", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "layer_slots"), active_index, &active_input_ptr); } else { uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "file_slots", ptr, "active_input_index", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"), active_index, &active_input_ptr); } diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 76a096b8471..5b478d8bde3 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -148,14 +148,14 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa) col = uiLayoutColumn(split, true); uiItemL(col, IFACE_("Inputs:"), ICON_NONE); uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "inputs", &ptr, "inputs", &ptr, "active_input", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&opptr, "in_out", SOCK_IN); col = uiLayoutColumn(split, true); uiItemL(col, IFACE_("Outputs:"), ICON_NONE); uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "outputs", &ptr, "outputs", &ptr, "active_output", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&opptr, "in_out", SOCK_OUT); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index b5eeebae664..718a9dd7c6e 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -826,6 +826,8 @@ void RNA_api_ui_layout(StructRNA *srna) parm = RNA_def_string(func, "active_propname", NULL, 0, "", "Identifier of the integer property in active_data, index of the active item"); RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_string(func, "item_dyntip_propname", NULL, 0, "", + "Identifier of a string property in items, to use as tooltip content"); RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Default and minimum number of rows to display", 0, INT_MAX); RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Default maximum number of rows to display", 0, INT_MAX); RNA_def_enum(func, "type", uilist_layout_type_items, UILST_LAYOUT_DEFAULT, "Type", "Type of layout to use"); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 21c69ac6203..d8c26b92706 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -547,7 +547,7 @@ void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, const char *prop void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser) RET_NONE void uiTemplateList(struct uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, - int rows, int maxrows, int layout_type, int columns) RET_NONE + const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns) RET_NONE void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C) RET_NONE void uiTemplateOperatorSearch(struct uiLayout *layout) RET_NONE void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C) RET_NONE |