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:
authorCampbell Barton <ideasman42@gmail.com>2018-06-23 17:31:28 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-06-23 21:52:47 +0300
commit85c1e61375532e91d5fc37b1d754cf76c17f7721 (patch)
tree459ed56b972e108036dc1c7e097003f2b234fdd7 /source/blender/editors
parent2fa231a86b4179ed513da2469df877497b346162 (diff)
UI: Add user defined context menu
- Add/Remove from RMB context menu. - Stored in user preferences. - Access from Q key. See T55027.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/ED_screen.h13
-rw-r--r--source/blender/editors/interface/interface_handlers.c45
-rw-r--r--source/blender/editors/screen/CMakeLists.txt1
-rw-r--r--source/blender/editors/screen/screen_user_menu.c142
-rw-r--r--source/blender/editors/space_api/spacetypes.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h1
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c130
8 files changed, 202 insertions, 137 deletions
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_TYPENAME)))
+ {
+ return umi;
+ }
+ }
+ }
+ return NULL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Menu Definition
+ * \{ */
+
+static void screen_user_menu_draw(const bContext *C, Menu *menu)
+{
+ 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 ((ELEM(umi->space_type, SPACE_TOPBAR) || (sl->spacetype == umi->space_type)) &&
+ (STREQLEN(context, umi->context, OP_MAX_TYPENAME)))
+ {
+ IDProperty *prop = umi->prop ? IDP_CopyProperty(umi->prop) : NULL;
+ uiItemFullO(
+ menu->layout, umi->opname, umi->ui_name[0] ? umi->ui_name : NULL,
+ ICON_NONE, prop, umi->opcontext, 0, NULL);
+ }
+ }
+}
+
+void ED_screen_user_menu_register(void)
+{
+ MenuType *mt = MEM_callocN(sizeof(MenuType), __func__);
+ strcpy(mt->idname, "SCREEN_MT_user_menu");
+ strcpy(mt->label, "Quick Favourites");
+ strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ mt->draw = screen_user_menu_draw;
+ WM_menutype_add(mt);
+}
+
+/** \} */
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 33ec7f771ba..2ee791e81d6 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -127,6 +127,8 @@ void ED_spacetypes_init(void)
ED_operatortypes_view2d();
ED_operatortypes_ui();
+ ED_screen_user_menu_register();
+
/* manipulator types */
ED_manipulatortypes_button_2d();
ED_manipulatortypes_dial_3d();
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 75267e990f7..4f960959abf 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -1541,11 +1541,6 @@ void ED_spacetype_view3d(void)
art->draw = view3d_tools_region_draw;
BLI_addhead(&st->regiontypes, art);
-#if 0
- /* unfinished still */
- view3d_toolshelf_register(art);
-#endif
-
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
art->regionid = RGN_TYPE_HEADER;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 017b31a0bf2..4eb2a016b94 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -235,7 +235,6 @@ struct Object *ED_view3d_cameracontrol_object_get(
/* view3d_toolbar.c */
void VIEW3D_OT_toolshelf(struct wmOperatorType *ot);
-void view3d_toolshelf_register(struct ARegionType *art);
/* view3d_snap.c */
bool ED_view3d_minmax_verts(struct Object *obedit, float min[3], float max[3]);
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index acceb40beaa..707e0e7a394 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -28,153 +28,24 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-
-#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_screen.h"
-
#include "WM_api.h"
#include "WM_types.h"
-#include "RNA_access.h"
-
#include "ED_screen.h"
-#include "ED_undo.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "view3d_intern.h" /* own include */
-/* ******************* */
-
-typedef struct CustomTool {
- struct CustomTool *next, *prev;
- char opname[OP_MAX_TYPENAME];
- char context[OP_MAX_TYPENAME];
-} CustomTool;
-
-static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
-{
- wmOperatorType *ot = arg2;
-
- if (ot) {
- CustomTool *ct = MEM_callocN(sizeof(CustomTool), "CustomTool");
-
- BLI_addtail(arg_listbase, ct);
- BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
- BLI_strncpy(ct->context, CTX_data_mode_string(C), OP_MAX_TYPENAME);
- }
-
-}
-
-static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
-{
- GHashIterator iter;
-
- for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
- wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
-
- if (BLI_strcasestr(ot->name, str)) {
- if (WM_operator_poll((bContext *)C, ot)) {
-
- if (false == UI_search_item_add(items, ot->name, ot, 0))
- break;
- }
- }
- }
-}
-
-
-/* ID Search browse menu, open */
-static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
-{
- static char search[OP_MAX_TYPENAME];
- wmEvent event;
- wmWindow *win = CTX_wm_window(C);
- uiBlock *block;
- uiBut *but;
-
- /* clear initial search string, then all items show */
- search[0] = 0;
-
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
-
- /* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
-
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
- UI_but_func_search_set(but, NULL, operator_search_cb, arg_listbase, operator_call_cb, NULL);
-
- UI_block_bounds_set_normal(block, 6);
- UI_block_direction_set(block, UI_DIR_DOWN);
- UI_block_end(C, block);
-
- wm_event_init_from_window(win, &event);
- event.type = EVT_BUT_OPEN;
- event.val = KM_PRESS;
- event.customdata = but;
- event.customdatafree = false;
- wm_event_add(win, &event);
-
- return block;
-}
-
-
-static void view3d_panel_tool_shelf(const bContext *C, Panel *pa)
-{
- SpaceLink *sl = CTX_wm_space_data(C);
- SpaceType *st = NULL;
- uiLayout *col;
- const char *context = CTX_data_mode_string(C);
-
- if (sl)
- st = BKE_spacetype_from_id(sl->spacetype);
-
- if (st && st->toolshelf.first) {
- CustomTool *ct;
-
- for (ct = st->toolshelf.first; ct; ct = ct->next) {
- if (STREQLEN(context, ct->context, OP_MAX_TYPENAME)) {
- col = uiLayoutColumn(pa->layout, true);
- uiItemFullO(col, ct->opname, NULL, ICON_NONE, NULL, WM_OP_INVOKE_REGION_WIN, 0, NULL);
- }
- }
- }
- col = uiLayoutColumn(pa->layout, true);
- uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &st->toolshelf, "Add Tool", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add Tool in shelf, gets saved in files");
-}
-
-
-void view3d_toolshelf_register(ARegionType *art)
-{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel tools");
- strcpy(pt->idname, "VIEW3D_PT_tool_shelf");
- strcpy(pt->label, N_("Tool Shelf"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = view3d_panel_tool_shelf;
- BLI_addtail(&art->paneltypes, pt);
-}
-
/* ********** operator to open/close toolshelf region */
static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op))
@@ -200,4 +71,3 @@ void VIEW3D_OT_toolshelf(wmOperatorType *ot)
/* flags */
ot->flag = 0;
}
-