Commit: 6a13b6324b42fedb0ad886e6c64816358058d627
Author: Campbell Barton
Date:   Sat Jun 30 20:59:10 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB6a13b6324b42fedb0ad886e6c64816358058d627

UI: support check-boxes in quick menu

Could support other RNA types,
however menus don't work well in this case.

===================================================================

M       source/blender/blenkernel/intern/blender_user_menu.c
M       source/blender/blenloader/intern/writefile.c
M       source/blender/editors/include/ED_screen.h
M       source/blender/editors/interface/interface_context_menu.c
M       source/blender/editors/screen/screen_user_menu.c
M       source/blender/makesdna/DNA_userdef_types.h
M       source/blender/windowmanager/WM_api.h
M       source/blender/windowmanager/intern/wm_operators.c

===================================================================

diff --git a/source/blender/blenkernel/intern/blender_user_menu.c 
b/source/blender/blenkernel/intern/blender_user_menu.c
index 387776aa144..3ec46e23cd1 100644
--- a/source/blender/blenkernel/intern/blender_user_menu.c
+++ b/source/blender/blenkernel/intern/blender_user_menu.c
@@ -76,14 +76,17 @@ bUserMenuItem *BKE_blender_user_menu_item_add(ListBase *lb, 
int type)
 {
        uint size;
 
-       if (type == USER_MENU_TYPE_OPERATOR) {
+       if (type == USER_MENU_TYPE_SEP) {
+               size = sizeof(bUserMenuItem);
+       }
+       else if (type == USER_MENU_TYPE_OPERATOR) {
                size = sizeof(bUserMenuItem_Op);
        }
        else if (type == USER_MENU_TYPE_MENU) {
                size = sizeof(bUserMenuItem_Menu);
        }
-       else if (type == USER_MENU_TYPE_SEP) {
-               size = sizeof(bUserMenuItem);
+       else if (type == USER_MENU_TYPE_PROP) {
+               size = sizeof(bUserMenuItem_Prop);
        }
        else {
                BLI_assert(0);
diff --git a/source/blender/blenloader/intern/writefile.c 
b/source/blender/blenloader/intern/writefile.c
index 61762b5d7ed..e7bca4c7e5b 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1254,6 +1254,14 @@ static void write_userdef(WriteData *wd, const UserDef 
*userdef)
                                        IDP_WriteProperty(umi_op->prop, wd);
                                }
                        }
+                       else if (umi->type == USER_MENU_TYPE_MENU) {
+                               const bUserMenuItem_Menu *umi_mt = (const 
bUserMenuItem_Menu *)umi;
+                               writestruct(wd, DATA, bUserMenuItem_Menu, 1, 
umi_mt);
+                       }
+                       else if (umi->type == USER_MENU_TYPE_PROP) {
+                               const bUserMenuItem_Prop *umi_pr = (const 
bUserMenuItem_Prop *)umi;
+                               writestruct(wd, DATA, bUserMenuItem_Prop, 1, 
umi_pr);
+                       }
                        else {
                                writestruct(wd, DATA, bUserMenuItem, 1, umi);
                        }
diff --git a/source/blender/editors/include/ED_screen.h 
b/source/blender/editors/include/ED_screen.h
index 0785b63ca37..5ff58da735f 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -63,6 +63,7 @@ struct wmMsgSubscribeValue;
 struct wmOperatorType;
 struct IDProperty;
 struct MenuType;
+struct PropertyRNA;
 
 /* regions */
 void    ED_region_do_listen(
@@ -330,6 +331,9 @@ struct bUserMenuItem_Op 
*ED_screen_user_menu_item_find_operator(
 struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu(
         struct ListBase *lb,
         const struct MenuType *mt);
+struct bUserMenuItem_Prop *ED_screen_user_menu_item_find_prop(
+        struct ListBase *lb,
+        const char *context_data_path, const char *prop_id, int prop_index);
 
 void ED_screen_user_menu_item_add_operator(
         struct ListBase *lb, const char *ui_name,
@@ -337,6 +341,9 @@ void ED_screen_user_menu_item_add_operator(
 void ED_screen_user_menu_item_add_menu(
         struct ListBase *lb, const char *ui_name,
         const struct MenuType *mt);
+void ED_screen_user_menu_item_add_prop(
+        ListBase *lb, const char *ui_name,
+        const char *context_data_path, const char *prop_id, int prop_index);
 
 void ED_screen_user_menu_item_remove(
         struct ListBase *lb, struct bUserMenuItem *umi);
diff --git a/source/blender/editors/interface/interface_context_menu.c 
b/source/blender/editors/interface/interface_context_menu.c
index d425ba1f985..240649c8ab0 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -216,12 +216,16 @@ static void popup_add_shortcut_func(bContext *C, void 
*arg1, void *UNUSED(arg2))
        UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, 
but, NULL);
 }
 
-static bool ui_but_is_user_menu_compatible(uiBut *but)
+static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but)
 {
-       return (but->optype || UI_but_menutype_get(but));
+       return (but->optype ||
+               (but->rnaprop &&
+                (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) &&
+                (WM_context_member_from_ptr(C, &but->rnapoin) != NULL)) ||
+               UI_but_menutype_get(but));
 }
 
-static bUserMenuItem *ui_but_user_menu_find(uiBut *but, bUserMenu *um)
+static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu 
*um)
 {
        MenuType *mt = NULL;
        if (but->optype) {
@@ -229,6 +233,12 @@ static bUserMenuItem *ui_but_user_menu_find(uiBut *but, 
bUserMenu *um)
                return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
                        &um->items, but->optype, prop, but->opcontext);
        }
+       else if (but->rnaprop) {
+               const char *member_id = WM_context_member_from_ptr(C, 
&but->rnapoin);
+               const char *prop_id = RNA_property_identifier(but->rnaprop);
+               return (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
+                       &um->items, member_id, prop_id, but->rnaindex);
+       }
        else if ((mt = UI_but_menutype_get(but))) {
                return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(
                        &um->items, mt);
@@ -238,9 +248,9 @@ static bUserMenuItem *ui_but_user_menu_find(uiBut *but, 
bUserMenu *um)
        }
 }
 
-static void ui_but_user_menu_add(uiBut *but, bUserMenu *um)
+static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
 {
-       BLI_assert(ui_but_is_user_menu_compatible(but));
+       BLI_assert(ui_but_is_user_menu_compatible(C, but));
 
        char drawstr[sizeof(but->drawstr)];
        STRNCPY(drawstr, but->drawstr);
@@ -257,6 +267,26 @@ static void ui_but_user_menu_add(uiBut *but, bUserMenu *um)
                        &um->items, drawstr,
                        but->optype, but->opptr ? but->opptr->data : NULL, 
but->opcontext);
        }
+       else if (but->rnaprop) {
+               /* Note: 'member_id' may be a path. */
+               const char *member_id = WM_context_member_from_ptr(C, 
&but->rnapoin);
+               const char *data_path = 
RNA_path_from_ID_to_struct(&but->rnapoin);
+               const char *member_id_data_path = member_id;
+               if (data_path) {
+                       member_id_data_path = BLI_sprintfN("%s.%s", member_id, 
data_path);
+               }
+               const char *prop_id = RNA_property_identifier(but->rnaprop);
+               /* Note, ignore 'drawstr', use property idname always. */
+               ED_screen_user_menu_item_add_prop(
+                       &um->items, "",
+                       member_id_data_path, prop_id, but->rnaindex);
+               if (data_path) {
+                       MEM_freeN((void *)data_path);
+               }
+               if (member_id != member_id_data_path) {
+                       MEM_freeN((void *)member_id_data_path);
+               }
+       }
        else if ((mt = UI_but_menutype_get(but))) {
                ED_screen_user_menu_item_add_menu(
                        &um->items, drawstr,
@@ -268,7 +298,7 @@ static void popup_user_menu_add_or_replace_func(bContext 
*C, void *arg1, void *U
 {
        uiBut *but = arg1;
        bUserMenu *um = ED_screen_user_menu_ensure(C);
-       ui_but_user_menu_add(but, um);
+       ui_but_user_menu_add(C, but, um);
 }
 
 static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void 
*arg2)
@@ -658,7 +688,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut 
*but)
        }
 
        /* Favorites Menu */
-       if (ui_but_is_user_menu_compatible(but)) {
+       if (ui_but_is_user_menu_compatible(C, but)) {
                uiBlock *block = uiLayoutGetBlock(layout);
                const int w = uiLayoutGetWidth(layout);
                uiBut *but2;
@@ -672,7 +702,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut 
*but)
 
                bUserMenu *um = ED_screen_user_menu_find(C);
                if (um) {
-                       bUserMenuItem *umi = ui_but_user_menu_find(but, um);
+                       bUserMenuItem *umi = ui_but_user_menu_find(C, but, um);
                        if (umi != NULL) {
                                but2 = uiDefIconTextBut(
                                        block, UI_BTYPE_BUT, 0, ICON_CANCEL,
diff --git a/source/blender/editors/screen/screen_user_menu.c 
b/source/blender/editors/screen/screen_user_menu.c
index c51227d7107..f62dc1ee500 100644
--- a/source/blender/editors/screen/screen_user_menu.c
+++ b/source/blender/editors/screen/screen_user_menu.c
@@ -56,6 +56,8 @@
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "RNA_access.h"
+
 /* -------------------------------------------------------------------- */
 /** \name Menu Type
  * \{ */
@@ -113,6 +115,24 @@ struct bUserMenuItem_Menu 
*ED_screen_user_menu_item_find_menu(
        return NULL;
 }
 
+struct bUserMenuItem_Prop *ED_screen_user_menu_item_find_prop(
+        struct ListBase *lb,
+        const char *context_data_path, const char *prop_id, int prop_index)
+{
+       for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
+               if (umi->type == USER_MENU_TYPE_PROP) {
+                       bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
+                       if (STREQ(context_data_path, umi_pr->context_data_path) 
&&
+                           STREQ(prop_id, umi_pr->prop_id) &&
+                           (prop_index == umi_pr->prop_index))
+                       {
+                               return umi_pr;
+                       }
+               }
+       }
+       return NULL;
+}
+
 void ED_screen_user_menu_item_add_operator(
         ListBase *lb, const char *ui_name,
         const wmOperatorType *ot, const IDProperty *prop, short opcontext)
@@ -137,6 +157,17 @@ void ED_screen_user_menu_item_add_menu(
        STRNCPY(umi_mt->mt_idname, mt->idname);
 }
 
+void ED_screen_user_menu_item_add_prop(
+        ListBase *lb, const char *ui_name,
+        const char *context_data_path, const char *prop_id, int prop_index)
+{
+       bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop 
*)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_PROP);
+       STRNCPY(umi_pr->item.ui_name, ui_name);
+       STRNCPY(umi_pr->context_data_path, context_data_path);
+       STRNCPY(umi_pr->prop_id, prop_id);
+       umi_pr->prop_index = prop_index;
+}
+
 void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
 {
        BLI_remlink(lb, umi);
@@ -176,6 +207,47 @@ static void screen_user_menu_draw(const bContext *C, Menu 
*menu)
                                uiItemM(menu->layout, umi_mt->mt_idname, 
ui_name,
                                        ICON_NONE);
                        }
+                       else if (umi->type == USER_MENU_TYPE_PROP) {
+                               bUserMenuItem_Prop *umi_pr = 
(bUserMenuItem_Prop *)umi;
+
+                               char *data_path = 
strchr(umi_pr->context_data_path, '.');
+                               if (data_path) {
+                                       *data_path = '\0';
+                               }
+                               PointerRNA ptr = CTX_data_pointer_get(C, 
umi_pr->context_data_path);
+                               if (ptr.type == NULL) {
+                                       PointerRNA ctx_ptr;
+                                       RNA_pointer_create(NULL, &RNA_Context, 
(void *)C, &ctx_ptr);
+                                       if (!RNA_path_resolve_full(&ctx_ptr, 
umi_pr->context_data_path, &ptr, NULL, NULL)) {
+                                               ptr.type = NULL;
+                                       }
+                               }
+                               if (data_path) {
+                                       *data_path = '.';
+                                       data_path += 1;
+                               }
+
+                               bool ok = false;
+                               if (ptr.type != NULL) {
+                                       PropertyRNA *prop = NULL;
+                                       PointerRNA prop_ptr = ptr;
+                                       if ((data_path == NULL) || 
RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NU

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to