diff options
5 files changed, 109 insertions, 17 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 47ecbca227b..142f4590c16 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -42,6 +42,7 @@ struct ID; struct IDProperty; struct ListBase; struct ARegion; +struct ARegionType; struct ScrArea; struct bScreen; struct wmEvent; @@ -428,6 +429,12 @@ void UI_popup_menu_but_set(uiPopupMenu *pup, struct ARegion *butregion, uiBut *b typedef struct uiPopover uiPopover; +void UI_popover_panel_from_type( + struct bContext *C, struct uiLayout *layout, struct PanelType *pt); +int UI_popover_panel_invoke( + struct bContext *C, int space_id, int region_id, const char *idname, + struct ReportList *reports); + uiPopover *UI_popover_begin(struct bContext *C) ATTR_NONNULL(1); void UI_popover_end(struct bContext *C, struct uiPopover *head, struct wmKeyMap *keymap); struct uiLayout *UI_popover_layout(uiPopover *head); @@ -836,6 +843,8 @@ struct PanelCategoryDyn *UI_panel_category_find_mouse_over(struct ARegion *ar, void UI_panel_category_clear_all(struct ARegion *ar); void UI_panel_category_draw_all(struct ARegion *ar, const char *category_id_active); +struct PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname); + /* Handlers * * Handlers that can be registered in regions, areas and windows for diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 58e654cb3c8..3a4d35296f7 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1848,33 +1848,19 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) layout->root->block->flag ^= UI_BLOCK_IS_FLIP; } -static void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_mt) +static void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt) { - PanelType *pt = (PanelType *)arg_mt; - - /* TODO: move into UI_paneltype_draw */ - Panel *panel = MEM_callocN(sizeof(Panel), "popover panel"); - panel->type = pt; + PanelType *pt = (PanelType *)arg_pt; if (layout->context) { CTX_store_set(C, layout->context); } - if (pt->draw_header) { - panel->layout = uiLayoutRow(layout, false); - pt->draw_header(C, panel); - panel->layout = NULL; - } - - panel->layout = layout; - pt->draw(C, panel); - panel->layout = NULL; + UI_popover_panel_from_type(C, layout, pt); if (layout->context) { CTX_store_set(C, NULL); } - - MEM_freeN(panel); } static uiBut *ui_item_menu( diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 121fdeb053d..7bf70b3d6fe 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -2272,3 +2272,14 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat ED_region_tag_redraw(ar); } +PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname) +{ + SpaceType *st = BKE_spacetype_from_id(space_id); + if (st) { + ARegionType *art = BKE_regiontype_from_id(st, region_id); + if (art) { + return BLI_findstring(&art->paneltypes, idname, offsetof(PanelType, idname)); + } + } + return NULL; +} diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c index 54776ad9c91..b6248d3daa1 100644 --- a/source/blender/editors/interface/interface_region_popover.c +++ b/source/blender/editors/interface/interface_region_popover.c @@ -56,6 +56,8 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_screen.h" +#include "BKE_report.h" #include "ED_screen.h" @@ -251,6 +253,63 @@ uiPopupBlockHandle *ui_popover_panel_create( /** \} */ /* -------------------------------------------------------------------- */ +/** \name Standard Popover Panels + * \{ */ + + +void UI_popover_panel_from_type(bContext *C, uiLayout *layout, PanelType *pt) +{ + /* TODO: move into UI_paneltype_draw */ + Panel *panel = MEM_callocN(sizeof(Panel), "popover panel"); + panel->type = pt; + + + if (pt->draw_header) { + panel->layout = uiLayoutRow(layout, false); + pt->draw_header(C, panel); + panel->layout = NULL; + } + + panel->layout = layout; + pt->draw(C, panel); + panel->layout = NULL; + + MEM_freeN(panel); +} + +int UI_popover_panel_invoke( + bContext *C, int space_id, int region_id, const char *idname, + ReportList *reports) +{ + uiLayout *layout; + PanelType *pt = UI_paneltype_find(space_id, region_id, idname); + if (pt == NULL) { + BKE_reportf( + reports, RPT_ERROR, + "Panel \"%s\" not found (space %d, region %d)", + idname, space_id, region_id); + return OPERATOR_CANCELLED; + } + + if (pt->poll && (pt->poll(C, pt) == false)) { + /* cancel but allow event to pass through, just like operators do */ + return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); + } + + uiPopover *pup = UI_popover_begin(C); + + layout = UI_popover_layout(pup); + + UI_popover_panel_from_type(C, layout, pt); + + UI_popover_end(C, pup, NULL); + + return OPERATOR_INTERFACE; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Popup Menu API with begin & end * \{ */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 6b7ca4ae2e5..1fe0799d6c1 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2241,6 +2241,32 @@ static void WM_OT_call_menu_pie(wmOperatorType *ot) RNA_def_string(ot->srna, "name", NULL, BKE_ST_MAXNAME, "Name", "Name of the pie menu"); } +static int wm_call_panel_exec(bContext *C, wmOperator *op) +{ + char idname[BKE_ST_MAXNAME]; + RNA_string_get(op->ptr, "name", idname); + const int space_type = RNA_enum_get(op->ptr, "space_type"); + const int region_type = RNA_enum_get(op->ptr, "region_type"); + + return UI_popover_panel_invoke(C, space_type, region_type, idname, op->reports); +} + +static void WM_OT_call_panel(wmOperatorType *ot) +{ + ot->name = "Call Panel"; + ot->idname = "WM_OT_call_panel"; + ot->description = "Call (draw) a pre-defined panel"; + + ot->exec = wm_call_panel_exec; + ot->poll = WM_operator_winactive; + + ot->flag = OPTYPE_INTERNAL; + + RNA_def_string(ot->srna, "name", NULL, BKE_ST_MAXNAME, "Name", "Name of the menu"); + RNA_def_enum(ot->srna, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Space Type", ""); + RNA_def_enum(ot->srna, "region_type", rna_enum_region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); +} + /* ************ window / screen operator definitions ************** */ /* this poll functions is needed in place of WM_operator_winactive @@ -3706,6 +3732,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_search_menu); WM_operatortype_append(WM_OT_call_menu); WM_operatortype_append(WM_OT_call_menu_pie); + WM_operatortype_append(WM_OT_call_panel); WM_operatortype_append(WM_OT_radial_control); WM_operatortype_append(WM_OT_stereo3d_set); #if defined(WIN32) |