UI: support operator enums in Quick Favorites #107616
|
@ -609,9 +609,15 @@ bool ED_operator_camera_poll(struct bContext *C);
|
||||||
bUserMenu **ED_screen_user_menus_find(const struct bContext *C, uint *r_len);
|
bUserMenu **ED_screen_user_menus_find(const struct bContext *C, uint *r_len);
|
||||||
struct bUserMenu *ED_screen_user_menu_ensure(struct bContext *C);
|
struct bUserMenu *ED_screen_user_menu_ensure(struct bContext *C);
|
||||||
|
|
||||||
|
/** Finds a menu item associated with an operator in user menus (aka Quick Favorites)
|
||||||
|
*
|
||||||
|
* \param op_prop_enum: name of an operator property when the operator is called with an enum (to
|
||||||
|
* be an empty string otherwise)
|
||||||
|
|||||||
|
*/
|
||||||
struct bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(struct ListBase *lb,
|
struct bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(struct ListBase *lb,
|
||||||
const struct wmOperatorType *ot,
|
const struct wmOperatorType *ot,
|
||||||
struct IDProperty *prop,
|
struct IDProperty *prop,
|
||||||
|
const char *op_prop_enum,
|
||||||
wmOperatorCallContext opcontext);
|
wmOperatorCallContext opcontext);
|
||||||
struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu(struct ListBase *lb,
|
struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu(struct ListBase *lb,
|
||||||
const struct MenuType *mt);
|
const struct MenuType *mt);
|
||||||
|
@ -624,6 +630,7 @@ void ED_screen_user_menu_item_add_operator(struct ListBase *lb,
|
||||||
const char *ui_name,
|
const char *ui_name,
|
||||||
const struct wmOperatorType *ot,
|
const struct wmOperatorType *ot,
|
||||||
const struct IDProperty *prop,
|
const struct IDProperty *prop,
|
||||||
|
const char *op_prop_enum,
|
||||||
wmOperatorCallContext opcontext);
|
wmOperatorCallContext opcontext);
|
||||||
void ED_screen_user_menu_item_add_menu(struct ListBase *lb,
|
void ED_screen_user_menu_item_add_menu(struct ListBase *lb,
|
||||||
const char *ui_name,
|
const char *ui_name,
|
||||||
|
|
|
@ -326,6 +326,9 @@ static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but)
|
||||||
else if (UI_but_menutype_get(but)) {
|
else if (UI_but_menutype_get(but)) {
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
else if (UI_but_operatortype_get_from_enum_menu(but, nullptr)) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -335,7 +338,7 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *
|
||||||
if (but->optype) {
|
if (but->optype) {
|
||||||
IDProperty *prop = (but->opptr) ? static_cast<IDProperty *>(but->opptr->data) : nullptr;
|
IDProperty *prop = (but->opptr) ? static_cast<IDProperty *>(but->opptr->data) : nullptr;
|
||||||
return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
|
return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
|
||||||
&um->items, but->optype, prop, but->opcontext);
|
&um->items, but->optype, prop, "", but->opcontext);
|
||||||
}
|
}
|
||||||
if (but->rnaprop) {
|
if (but->rnaprop) {
|
||||||
char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
||||||
|
@ -346,6 +349,13 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *
|
||||||
return umi;
|
return umi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wmOperatorType *ot = nullptr;
|
||||||
|
PropertyRNA *prop_enum = nullptr;
|
||||||
|
if ((ot = UI_but_operatortype_get_from_enum_menu(but, &prop_enum))) {
|
||||||
|
return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
|
||||||
|
&um->items, ot, nullptr, RNA_property_identifier(prop_enum), but->opcontext);
|
||||||
|
}
|
||||||
|
|
||||||
MenuType *mt = UI_but_menutype_get(but);
|
MenuType *mt = UI_but_menutype_get(but);
|
||||||
if (mt != nullptr) {
|
if (mt != nullptr) {
|
||||||
return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(&um->items, mt);
|
return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(&um->items, mt);
|
||||||
|
@ -360,7 +370,11 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
||||||
char drawstr[sizeof(but->drawstr)];
|
char drawstr[sizeof(but->drawstr)];
|
||||||
ui_but_drawstr_without_sep_char(but, drawstr, sizeof(drawstr));
|
ui_but_drawstr_without_sep_char(but, drawstr, sizeof(drawstr));
|
||||||
|
|
||||||
|
/* Used for USER_MENU_TYPE_MENU. */
|
||||||
MenuType *mt = nullptr;
|
MenuType *mt = nullptr;
|
||||||
|
/* Used for USER_MENU_TYPE_OPERATOR (property enum used). */
|
||||||
|
wmOperatorType *ot = nullptr;
|
||||||
|
PropertyRNA *prop = nullptr;
|
||||||
if (but->optype) {
|
if (but->optype) {
|
||||||
if (drawstr[0] == '\0') {
|
if (drawstr[0] == '\0') {
|
||||||
/* Hard code overrides for generic operators. */
|
/* Hard code overrides for generic operators. */
|
||||||
|
@ -397,6 +411,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
||||||
drawstr,
|
drawstr,
|
||||||
but->optype,
|
but->optype,
|
||||||
but->opptr ? static_cast<const IDProperty *>(but->opptr->data) : nullptr,
|
but->opptr ? static_cast<const IDProperty *>(but->opptr->data) : nullptr,
|
||||||
|
"",
|
||||||
but->opcontext);
|
but->opcontext);
|
||||||
}
|
}
|
||||||
else if (but->rnaprop) {
|
else if (but->rnaprop) {
|
||||||
|
@ -410,6 +425,14 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
||||||
else if ((mt = UI_but_menutype_get(but))) {
|
else if ((mt = UI_but_menutype_get(but))) {
|
||||||
ED_screen_user_menu_item_add_menu(&um->items, drawstr, mt);
|
ED_screen_user_menu_item_add_menu(&um->items, drawstr, mt);
|
||||||
}
|
}
|
||||||
|
else if ((ot = UI_but_operatortype_get_from_enum_menu(but, &prop))) {
|
||||||
|
ED_screen_user_menu_item_add_operator(&um->items,
|
||||||
|
WM_operatortype_name(ot, nullptr),
|
||||||
|
ot,
|
||||||
|
nullptr,
|
||||||
|
RNA_property_identifier(prop),
|
||||||
|
but->opcontext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void * /*arg2*/)
|
static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void * /*arg2*/)
|
||||||
|
|
|
@ -97,13 +97,18 @@ bUserMenu *ED_screen_user_menu_ensure(bContext *C)
|
||||||
bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(ListBase *lb,
|
bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(ListBase *lb,
|
||||||
const wmOperatorType *ot,
|
const wmOperatorType *ot,
|
||||||
IDProperty *prop,
|
IDProperty *prop,
|
||||||
|
const char *op_prop_enum,
|
||||||
wmOperatorCallContext opcontext)
|
wmOperatorCallContext opcontext)
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (bUserMenuItem *, umi, lb) {
|
LISTBASE_FOREACH (bUserMenuItem *, umi, lb) {
|
||||||
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
||||||
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
||||||
if (STREQ(ot->idname, umi_op->op_idname) && (opcontext == umi_op->opcontext) &&
|
const bool ok_idprop = prop ? IDP_EqualsProperties(prop, umi_op->prop) : true;
|
||||||
IDP_EqualsProperties(prop, umi_op->prop))
|
const bool ok_prop_enum = (umi_op->op_prop_enum[0] != '\0') ?
|
||||||
|
STREQ(umi_op->op_prop_enum, op_prop_enum) :
|
||||||
|
true;
|
||||||
|
if (STREQ(ot->idname, umi_op->op_idname) && (opcontext == umi_op->opcontext) && ok_idprop &&
|
||||||
|
ok_prop_enum)
|
||||||
{
|
{
|
||||||
return umi_op;
|
return umi_op;
|
||||||
}
|
}
|
||||||
|
@ -148,6 +153,7 @@ void ED_screen_user_menu_item_add_operator(ListBase *lb,
|
||||||
const char *ui_name,
|
const char *ui_name,
|
||||||
const wmOperatorType *ot,
|
const wmOperatorType *ot,
|
||||||
const IDProperty *prop,
|
const IDProperty *prop,
|
||||||
|
const char *op_prop_enum,
|
||||||
wmOperatorCallContext opcontext)
|
wmOperatorCallContext opcontext)
|
||||||
{
|
{
|
||||||
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(
|
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(
|
||||||
|
@ -157,6 +163,7 @@ void ED_screen_user_menu_item_add_operator(ListBase *lb,
|
||||||
STRNCPY(umi_op->item.ui_name, ui_name);
|
STRNCPY(umi_op->item.ui_name, ui_name);
|
||||||
}
|
}
|
||||||
STRNCPY(umi_op->op_idname, ot->idname);
|
STRNCPY(umi_op->op_idname, ot->idname);
|
||||||
|
STRNCPY(umi_op->op_prop_enum, op_prop_enum);
|
||||||
umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL;
|
umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,15 +223,28 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu)
|
||||||
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
||||||
wmOperatorType *ot = WM_operatortype_find(umi_op->op_idname, false);
|
wmOperatorType *ot = WM_operatortype_find(umi_op->op_idname, false);
|
||||||
if (ot != NULL) {
|
if (ot != NULL) {
|
||||||
IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
|
if (umi_op->op_prop_enum[0] == '\0') {
|
||||||
uiItemFullO_ptr(menu->layout,
|
IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
|
||||||
ot,
|
uiItemFullO_ptr(menu->layout,
|
||||||
CTX_IFACE_(ot->translation_context, ui_name),
|
ot,
|
||||||
ICON_NONE,
|
CTX_IFACE_(ot->translation_context, ui_name),
|
||||||
prop,
|
ICON_NONE,
|
||||||
umi_op->opcontext,
|
prop,
|
||||||
0,
|
umi_op->opcontext,
|
||||||
NULL);
|
0,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* umi_op->prop could be used to set other properties but it's currently unsupported.
|
||||||
|
*/
|
||||||
|
uiItemMenuEnumFullO_ptr(menu->layout,
|
||||||
Campbell Barton
commented
It's possible we want to support assigning additional properties even with Nevertheless, it's worth adding a comment that It's possible we want to support assigning additional properties even with `op_prop_enum` set, although I'm not sure if there are practical cases which would use this of hand.
Nevertheless, it's worth adding a comment that `umi_op->prop` could be used to set other properties but it's currently unsupported.
Philipp Oeser
commented
added that comment added that comment
|
|||||||
|
C,
|
||||||
|
ot,
|
||||||
|
umi_op->op_prop_enum,
|
||||||
|
CTX_IFACE_(ot->translation_context, ui_name),
|
||||||
|
ICON_NONE,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
is_empty = false;
|
is_empty = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -565,6 +565,7 @@ typedef struct bUserMenuItem_Op {
|
||||||
bUserMenuItem item;
|
bUserMenuItem item;
|
||||||
char op_idname[64];
|
char op_idname[64];
|
||||||
struct IDProperty *prop;
|
struct IDProperty *prop;
|
||||||
|
char op_prop_enum[64];
|
||||||
char opcontext; /* #wmOperatorCallContext */
|
char opcontext; /* #wmOperatorCallContext */
|
||||||
char _pad0[7];
|
char _pad0[7];
|
||||||
} bUserMenuItem_Op;
|
} bUserMenuItem_Op;
|
||||||
|
|
Loading…
Reference in New Issue
Doc-string should note this is to be an empty string when not set.
done