UI: popup panel operator, as we have for menus
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
@@ -250,6 +252,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
|
||||
* \{ */
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user