Commit: 85c1e61375532e91d5fc37b1d754cf76c17f7721
Author: Campbell Barton
Date:   Sat Jun 23 16:31:28 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB85c1e61375532e91d5fc37b1d754cf76c17f7721

UI: Add user defined context menu

- Add/Remove from RMB context menu.
- Stored in user preferences.
- Access from Q key.

See T55027.

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

M       source/blender/blenkernel/BKE_screen.h
M       source/blender/blenkernel/intern/blender.c
M       source/blender/blenkernel/intern/screen.c
M       source/blender/blenloader/intern/readfile.c
M       source/blender/blenloader/intern/writefile.c
M       source/blender/editors/include/ED_screen.h
M       source/blender/editors/interface/interface_handlers.c
M       source/blender/editors/screen/CMakeLists.txt
A       source/blender/editors/screen/screen_user_menu.c
M       source/blender/editors/space_api/spacetypes.c
M       source/blender/editors/space_view3d/space_view3d.c
M       source/blender/editors/space_view3d/view3d_intern.h
M       source/blender/editors/space_view3d/view3d_toolbar.c
M       source/blender/makesdna/DNA_userdef_types.h
M       source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/source/blender/blenkernel/BKE_screen.h 
b/source/blender/blenkernel/BKE_screen.h
index 1b42ce97940..d2c2f9a254f 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -121,9 +121,6 @@ typedef struct SpaceType {
        /* region type definitions */
        ListBase regiontypes;
 
-       /* tool shelf definitions */
-       ListBase toolshelf;
-
        /* read and write... */
 
        /* default keymaps to add */
diff --git a/source/blender/blenkernel/intern/blender.c 
b/source/blender/blenkernel/intern/blender.c
index c366d822648..7b41bb62872 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -241,6 +241,15 @@ void BKE_blender_userdef_data_free(UserDef *userdef, bool 
clear_fonts)
        BLI_freelistN(&userdef->uifonts);
        BLI_freelistN(&userdef->themes);
 
+       for (bUserMenuItem *umi = userdef->user_menu_items.first, *umi_next; 
umi; umi = umi_next) {
+               umi_next = umi->next;
+               if (umi->prop) {
+                       IDP_FreeProperty(umi->prop);
+                       MEM_freeN(umi->prop);
+               }
+               MEM_freeN(umi);
+       }
+
 #undef U
 }
 
diff --git a/source/blender/blenkernel/intern/screen.c 
b/source/blender/blenkernel/intern/screen.c
index 5a6c55a9fcc..4a840b5ffbe 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -88,8 +88,6 @@ static void spacetype_free(SpaceType *st)
        }
 
        BLI_freelistN(&st->regiontypes);
-       BLI_freelistN(&st->toolshelf);
-
 }
 
 void BKE_spacetypes_free(void)
diff --git a/source/blender/blenloader/intern/readfile.c 
b/source/blender/blenloader/intern/readfile.c
index a169dc82d1f..22bd3ee3a17 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8713,6 +8713,12 @@ static BHead *read_userdef(BlendFileData *bfd, FileData 
*fd, BHead *bhead)
        user->uifonts.first = user->uifonts.last= NULL;
 
        link_list(fd, &user->uistyles);
+       link_list(fd, &user->user_menu_items);
+
+       for (bUserMenuItem *umi = user->user_menu_items.first; umi; umi = 
umi->next) {
+               umi->prop = newdataadr(fd, umi->prop);
+               IDP_DirectLinkGroup_OrFree(&umi->prop, (fd->flags & 
FD_FLAGS_SWITCH_ENDIAN), fd);
+       }
 
        /* free fd->datamap again */
        oldnewmap_free_unused(fd->datamap);
diff --git a/source/blender/blenloader/intern/writefile.c 
b/source/blender/blenloader/intern/writefile.c
index 9c55c949fcf..5652ad895d3 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1258,6 +1258,13 @@ static void write_userdef(WriteData *wd, const UserDef 
*userdef)
        for (const uiStyle *style = userdef->uistyles.first; style; style = 
style->next) {
                writestruct(wd, DATA, uiStyle, 1, style);
        }
+
+       for (const bUserMenuItem *umi = userdef->user_menu_items.first; umi; 
umi = umi->next) {
+               writestruct(wd, DATA, bUserMenuItem, 1, umi);
+               if (umi->prop) {
+                       IDP_WriteProperty(umi->prop, wd);
+               }
+       }
 }
 
 static void write_boid_state(WriteData *wd, BoidState *state)
diff --git a/source/blender/editors/include/ED_screen.h 
b/source/blender/editors/include/ED_screen.h
index 9fcefc1e4b1..05b51dff4b4 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -60,6 +60,8 @@ struct Main;
 struct wmMsgBus;
 struct wmMsgSubscribeKey;
 struct wmMsgSubscribeValue;
+struct wmOperatorType;
+struct IDProperty;
 
 /* regions */
 void    ED_region_do_listen(
@@ -311,6 +313,16 @@ int     ED_operator_posemode_local(struct bContext *C);
 int     ED_operator_mask(struct bContext *C);
 int     ED_operator_camera(struct bContext *C);
 
+/* screen_user_menu.c */
+
+void ED_screen_user_menu_add(
+        struct bContext *C, const char *ui_name,
+        struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
+void ED_screen_user_menu_remove(struct bUserMenuItem *umi);
+struct bUserMenuItem *ED_screen_user_menu_find(
+        struct bContext *C,
+        struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
+void ED_screen_user_menu_register(void);
 
 /* Cache display helpers */
 
@@ -333,4 +345,3 @@ void ED_area_type_hud_ensure(struct bContext *C, struct 
ScrArea *sa);
 #define ED_KEYMAP_HEADER    64
 
 #endif /* __ED_SCREEN_H__ */
-
diff --git a/source/blender/editors/interface/interface_handlers.c 
b/source/blender/editors/interface/interface_handlers.c
index cb37c301031..6f3bbc5ab36 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -6649,6 +6649,30 @@ 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 void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void 
*arg2)
+{
+       uiBut *but = arg1;
+       bUserMenuItem *umi = arg2;
+       if (umi) {
+               ED_screen_user_menu_remove(umi);
+       }
+       char drawstr[sizeof(but->drawstr)];
+       STRNCPY(drawstr, but->drawstr);
+       if (but->flag & UI_BUT_HAS_SEP_CHAR) {
+               char *sep = strrchr(drawstr, UI_SEP_CHAR);
+               if (sep) {
+                       *sep = '\0';
+               }
+       }
+       ED_screen_user_menu_add(C, drawstr, but->optype, but->opptr ? 
but->opptr->data : NULL, but->opcontext);
+}
+
+static void popup_user_menu_remove_func(bContext *UNUSED(C), void 
*UNUSED(arg1), void *arg2)
+{
+       bUserMenuItem *umi = arg2;
+       ED_screen_user_menu_remove(umi);
+}
+
 /**
  * menu to chow when right clicking on the panel header
  */
@@ -7021,6 +7045,27 @@ static bool ui_but_menu(bContext *C, uiBut *but)
                        UI_but_func_set(but2, popup_add_shortcut_func, but, 
NULL);
                }
 
+               uiItemS(layout);
+
+               {
+                       bUserMenuItem *umi = ED_screen_user_menu_find(
+                               C, but->optype, but->opptr ? but->opptr->data : 
NULL, but->opcontext);
+
+                       but2 = uiDefIconTextBut(
+                               block, UI_BTYPE_BUT, 0, ICON_MENU_PANEL,
+                               CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, 
"Add to Favourites Menu"),
+                               0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
+                               "Add to a user defined context menu (stored in 
the user preferences)");
+                       UI_but_func_set(but2, 
popup_user_menu_add_or_replace_func, but, umi);
+                       if (umi) {
+                               but2 = uiDefIconTextBut(
+                                       block, UI_BTYPE_BUT, 0, ICON_CANCEL,
+                                       
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Favourites Menu"),
+                                       0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, 
"");
+                               UI_but_func_set(but2, 
popup_user_menu_remove_func, NULL, umi);
+                       }
+               }
+
                /* Set the operator pointer for python access */
                uiLayoutSetContextFromBut(layout, but);
 
diff --git a/source/blender/editors/screen/CMakeLists.txt 
b/source/blender/editors/screen/CMakeLists.txt
index 29b9971eabb..ee114eba3c5 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
        screen_draw.c
        screen_edit.c
        screen_ops.c
+       screen_user_menu.c
        screendump.c
        workspace_edit.c
        workspace_layout_edit.c
diff --git a/source/blender/editors/screen/screen_user_menu.c 
b/source/blender/editors/screen/screen_user_menu.c
new file mode 100644
index 00000000000..5a05b55675e
--- /dev/null
+++ b/source/blender/editors/screen/screen_user_menu.c
@@ -0,0 +1,142 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/screen/screen_user_menu.c
+ *  \ingroup spview3d
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_context.h"
+#include "BKE_screen.h"
+#include "BKE_idprop.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Utilities
+ * \{ */
+
+void ED_screen_user_menu_add(
+        bContext *C, const char *ui_name,
+        wmOperatorType *ot, IDProperty *prop, short opcontext)
+{
+       SpaceLink *sl = CTX_wm_space_data(C);
+       bUserMenuItem *umi = MEM_callocN(sizeof(bUserMenuItem), __func__);
+       umi->space_type = sl ? sl->spacetype : SPACE_EMPTY;
+       umi->opcontext = opcontext;
+       if (!STREQ(ui_name, ot->name)) {
+               BLI_strncpy(umi->ui_name, ui_name, OP_MAX_TYPENAME);
+       }
+       BLI_strncpy(umi->opname, ot->idname, OP_MAX_TYPENAME);
+       BLI_strncpy(umi->context, CTX_data_mode_string(C), OP_MAX_TYPENAME);
+       umi->prop = prop ? IDP_CopyProperty(prop) : NULL;
+       BLI_addtail(&U.user_menu_items, umi);
+}
+
+void ED_screen_user_menu_remove(bUserMenuItem *umi)
+{
+       BLI_remlink(&U.user_menu_items, umi);
+       if (umi->prop) {
+               IDP_FreeProperty(umi->prop);
+               MEM_freeN(umi->prop);
+       }
+       MEM_freeN(umi);
+}
+
+bUserMenuItem *ED_screen_user_menu_find(
+        bContext *C,
+        wmOperatorType *ot, IDProperty *prop, short opcontext)
+{
+       SpaceLink *sl = CTX_wm_space_data(C);
+       const char *context = CTX_data_mode_string(C);
+       for (bUserMenuItem *umi = U.user_menu_items.first; umi; umi = 
umi->next) {
+               if (STREQ(ot->idname, umi->opname) &&
+                   (opcontext == umi->opcontext) &&
+                   (IDP_EqualsProperties(prop, umi->prop)))
+               {
+                       if ((ELEM(umi->space_type, SPACE_TOPBAR) || 
(sl->spacetype == umi->space_type)) &&
+                           (STREQLEN(context, umi->context, OP_MAX_TY

@@ 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