UI: Initial popover support for panels

- UILayout.popover(.. panel_type ..)
  A single panel
- UILayout.popover_group(.. panel categories ..)
  Expands all panels matching args.

Currently used in the topbar for redo and paint options.
This commit is contained in:
Campbell Barton 2018-04-22 17:16:39 +02:00
parent b8e7991811
commit e6d1fb87c6
13 changed files with 581 additions and 1 deletions

@ -144,6 +144,15 @@ class WindowManager(bpy_types.ID):
finally:
self.popmenu_end__internal(popup)
def popover(self, draw_func, title="", icon='NONE'):
import bpy
popup = self.popover_begin__internal(title, icon)
try:
draw_func(popup, bpy.context)
finally:
self.popover_end__internal(popup)
def popup_menu_pie(self, event, draw_func, title="", icon='NONE'):
import bpy
pie = self.piemenu_begin__internal(title, icon, event)

@ -113,12 +113,37 @@ class TOPBAR_HT_lower_bar(Header):
act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[object_mode]
layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
mode = context.mode
# Example of how toolsettings can be accessed as pop-overs.
if mode == 'SCULPT':
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context="", category="Tools")
elif mode == 'PAINT_VERTEX':
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context="", category="Tools")
elif mode == 'PAINT_WEIGHT':
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context="", category="Tools")
elif mode == 'PAINT_TEXTURE':
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context="", category="Tools")
def draw_right(self, context):
layout = self.layout
# Placeholder
layout.operator("ed.undo_history", text="...")
# Last Action (redo)
layout.label("Last Action:")
operators = context.window_manager.operators
op = operators[-1] if operators else None
row = layout.row()
row.enabled = op is not None
row.popover(
space_type='VIEW_3D',
region_type='TOOL_PROPS',
panel_type="VIEW3D_PT_last_operator",
text=op.name if op else "Last Action...",
)
class INFO_MT_editor_menus(Menu):
bl_idname = "INFO_MT_editor_menus"

@ -265,6 +265,7 @@ typedef enum {
UI_BTYPE_CHECKBOX_N = (14 << 9),
UI_BTYPE_COLOR = (15 << 9),
UI_BTYPE_TAB = (16 << 9),
UI_BTYPE_POPOVER = (17 << 9),
UI_BTYPE_SCROLL = (18 << 9),
UI_BTYPE_BLOCK = (19 << 9),
UI_BTYPE_LABEL = (20 << 9),
@ -409,6 +410,17 @@ int UI_popup_menu_invoke(struct bContext *C, const char *idname, struct ReportLi
void UI_popup_menu_retval_set(const uiBlock *block, const int retval, const bool enable);
void UI_popup_menu_but_set(uiPopupMenu *pup, struct ARegion *butregion, uiBut *but);
/* interface_region_popover.c */
typedef struct uiPopover uiPopover;
uiPopover *UI_popover_begin(
struct bContext *C) ATTR_NONNULL();
uiPopover *UI_popover_begin_ex(
struct bContext *C, const char *block_name) ATTR_NONNULL();
void UI_popover_end(struct bContext *C, struct uiPopover *head);
struct uiLayout *UI_popover_layout(uiPopover *head);
/* interface_region_menu_pie.c */
/* Pie menus */
typedef struct uiPieMenu uiPieMenu;
@ -911,6 +923,7 @@ void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct Pointe
void uiLayoutContextCopy(uiLayout *layout, struct bContextStore *context);
const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing
struct MenuType *UI_but_menutype_get(uiBut *but);
struct PanelType *UI_but_paneltype_get(uiBut *but);
void UI_menutype_draw(struct bContext *C, struct MenuType *mt, struct uiLayout *layout);
/* Only for convenience. */
@ -1090,6 +1103,19 @@ void uiItemM(uiLayout *layout, struct bContext *C, const char *menuname, const c
void uiItemV(uiLayout *layout, const char *name, int icon, int argval); /* value */
void uiItemS(uiLayout *layout); /* separator */
void uiItemPopoverPanel_ptr(
uiLayout *layout, struct bContext *C,
struct PanelType *pt,
const char *name, int icon);
void uiItemPopoverPanel(
uiLayout *layout, struct bContext *C,
int space_id, int region_id, const char *panelname,
const char *name, int icon);
void uiItemPopoverPanelFromGroup(
uiLayout *layout, struct bContext *C,
int space_id, int region_id,
const char *context, const char *category);
void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg);
void uiItemMenuEnumO_ptr(uiLayout *layout, struct bContext *C, struct wmOperatorType *ot, const char *propname, const char *name, int icon);
void uiItemMenuEnumO(uiLayout *layout, struct bContext *C, const char *opname, const char *propname, const char *name, int icon);

@ -59,6 +59,7 @@ set(SRC
interface_region_color_picker.c
interface_region_menu_pie.c
interface_region_menu_popup.c
interface_region_popover.c
interface_region_popup.c
interface_region_search.c
interface_region_tooltip.c

@ -3431,6 +3431,7 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
uiBlockCreateFunc func = NULL;
uiBlockHandleCreateFunc handlefunc = NULL;
uiMenuCreateFunc menufunc = NULL;
uiMenuCreateFunc popoverfunc = NULL;
void *arg = NULL;
switch (but->type) {
@ -3450,6 +3451,11 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
menufunc = but->menu_create_func;
arg = but->poin;
break;
case UI_BTYPE_POPOVER:
BLI_assert(but->menu_create_func);
popoverfunc = but->menu_create_func;
arg = but->poin;
break;
case UI_BTYPE_COLOR:
ui_but_v3_get(but, data->origvec);
copy_v3_v3(data->vec, data->origvec);
@ -3474,6 +3480,11 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
if (but->block->handle)
data->menu->popup = but->block->handle->popup;
}
else if (popoverfunc) {
data->menu = ui_popover_panel_create(C, data->region, but, popoverfunc, arg);
if (but->block->handle)
data->menu->popup = but->block->handle->popup;
}
#ifdef USE_ALLSELECT
{
@ -7046,6 +7057,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
retval = ui_do_but_TEX(C, block, but, data, event);
break;
case UI_BTYPE_MENU:
case UI_BTYPE_POPOVER:
case UI_BTYPE_BLOCK:
case UI_BTYPE_PULLDOWN:
retval = ui_do_but_BLOCK(C, but, data, event);

@ -615,6 +615,18 @@ uiPopupBlockHandle *ui_popup_menu_create(
struct bContext *C, struct ARegion *butregion, uiBut *but,
uiMenuCreateFunc create_func, void *arg);
/* interface_region_popover.c */
uiBlock *ui_popover_block_refresh(
struct bContext *C, uiPopupBlockHandle *handle,
ARegion *butregion, uiBut *but);
uiPopupBlockHandle *ui_popover_block_create(
struct bContext *C, struct ARegion *butregion, uiBut *but,
uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
void *arg);
uiPopupBlockHandle *ui_popover_panel_create(
struct bContext *C, struct ARegion *butregion, uiBut *but,
uiMenuCreateFunc create_func, void *arg);
/* interface_region_menu_pie.c */
void ui_pie_menu_level_create(
uiBlock *block, struct wmOperatorType *ot, const char *propname, IDProperty *properties,

@ -1824,6 +1824,35 @@ 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)
{
PanelType *pt = (PanelType *)arg_mt;
/* TODO: move into UI_paneltype_draw */
Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
panel->type = 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;
if (layout->context) {
CTX_store_set(C, NULL);
}
MEM_freeN(panel);
}
static uiBut *ui_item_menu(
uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN,
const char *tip, bool force_menu)
@ -1901,6 +1930,79 @@ void uiItemM(uiLayout *layout, bContext *UNUSED(C), const char *menuname, const
ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL, TIP_(mt->description), false);
}
/* popover */
void uiItemPopoverPanel_ptr(uiLayout *layout, bContext *UNUSED(C), PanelType *pt, const char *name, int icon)
{
if (!name) {
name = CTX_IFACE_(pt->translation_context, pt->label);
}
if (layout->root->type == UI_LAYOUT_MENU && !icon)
icon = ICON_BLANK1;
uiBut *but = ui_item_menu(layout, name, icon, ui_item_paneltype_func, pt, NULL, NULL, false);
but->type = UI_BTYPE_POPOVER;
}
void uiItemPopoverPanel(
uiLayout *layout, bContext *C,
int space_id, int region_id, const char *panel_type,
const char *name, int icon)
{
SpaceType *st = BKE_spacetype_from_id(space_id);
if (st == NULL) {
RNA_warning("space type not found %d", space_id);
return;
}
ARegionType *art = BKE_regiontype_from_id(st, region_id);
if (art == NULL) {
RNA_warning("region type not found %d", region_id);
return;
}
PanelType *pt;
for (pt = art->paneltypes.first; pt; pt = pt->next) {
if (STREQ(pt->idname, panel_type)) {
break;
}
}
if (pt == NULL) {
RNA_warning("area type not found %s", panel_type);
return;
}
uiItemPopoverPanel_ptr(layout, C, pt, name, icon);
}
void uiItemPopoverPanelFromGroup(
uiLayout *layout, bContext *C,
int space_id, int region_id, const char *context, const char *category)
{
SpaceType *st = BKE_spacetype_from_id(space_id);
if (st == NULL) {
RNA_warning("space type not found %d", space_id);
return;
}
ARegionType *art = BKE_regiontype_from_id(st, region_id);
if (art == NULL) {
RNA_warning("region type not found %d", region_id);
return;
}
for (PanelType *pt = art->paneltypes.first; pt; pt = pt->next) {
/* Causes too many panels, check context. */
if (/* (*context == '\0') || */ STREQ(pt->context, context)) {
if ((*category == '\0') || STREQ(pt->category, category)) {
if (pt->poll == NULL || pt->poll(C, pt)) {
uiItemPopoverPanel_ptr(layout, C, pt, NULL, ICON_NONE);
}
}
}
}
}
/* label item */
static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
{
@ -3604,6 +3706,18 @@ MenuType *UI_but_menutype_get(uiBut *but)
}
}
/* this is a bit of a hack but best keep it in one place at least */
PanelType *UI_but_paneltype_get(uiBut *but)
{
if (but->menu_create_func == ui_item_paneltype_func) {
return (PanelType *)but->poin;
}
else {
return NULL;
}
}
void UI_menutype_draw(bContext *C, MenuType *mt, struct uiLayout *layout)
{
Menu menu = {

@ -0,0 +1,283 @@
/*
* ***** 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) 2008 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/interface/interface_region_popover.c
* \ingroup edinterface
*
* Pop-Over Region
*
* \note This is very close to 'interface_region_menu_popup.c'
*
* We could even merge them, however menu logic is already over-loaded.
* PopOver's have the following differences.
*
* - UI is not constrained to a list.
* - Pressing a button won't close the pop-over.
* - Different draw style (to show this is has different behavior from a menu).
* - #PanelType are used insetead of #MenuType.
* - No menu flipping support.
* - No moving the menu to fit the mouse cursor.
* - No key accelerators to access menu items
* (if we add support they would work differently).
* - No arrow key navigation.
* - No menu memory.
* - No title.
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_report.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "UI_interface.h"
#include "BLT_translation.h"
#include "ED_screen.h"
#include "interface_intern.h"
#include "interface_regions_intern.h"
/* -------------------------------------------------------------------- */
/** \name Popup Menu with Callback or String
* \{ */
struct uiPopover {
uiBlock *block;
uiLayout *layout;
uiBut *but;
ARegion *butregion;
int mx, my;
bool popover, slideout;
uiMenuCreateFunc menu_func;
void *menu_arg;
};
static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
{
uiBlock *block;
uiPopover *pup = arg_pup;
int offset[2], minwidth, width, height;
if (pup->menu_func) {
pup->block->handle = handle;
pup->menu_func(C, pup->layout, pup->menu_arg);
pup->block->handle = NULL;
}
if (pup->but) {
/* minimum width to enforece */
minwidth = BLI_rctf_size_x(&pup->but->rect);
}
else {
minwidth = 50;
}
block = pup->block;
/* in some cases we create the block before the region,
* so we set it delayed here if necessary */
if (BLI_findindex(&handle->region->uiblocks, block) == -1)
UI_block_region_set(block, handle->region);
block->direction = UI_DIR_DOWN;
UI_block_layout_resolve(block, &width, &height);
UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_KEEP_OPEN);
if (pup->popover) {
UI_block_flag_enable(block, UI_BLOCK_LOOP);
UI_block_direction_set(block, block->direction);
block->minbounds = minwidth;
UI_block_bounds_set_popup(block, 1, offset[0], offset[1]);
}
else {
/* for a header menu we set the direction automatic */
block->minbounds = minwidth;
UI_block_bounds_set_normal(block, 1);
}
/* if menu slides out of other menu, override direction */
if (pup->slideout)
UI_block_direction_set(block, UI_DIR_RIGHT);
return pup->block;
}
uiPopupBlockHandle *ui_popover_panel_create(
bContext *C, ARegion *butregion, uiBut *but,
uiMenuCreateFunc menu_func, void *arg)
{
wmWindow *window = CTX_wm_window(C);
uiStyle *style = UI_style_get_dpi();
uiPopupBlockHandle *handle;
uiPopover *pup;
pup = MEM_callocN(sizeof(uiPopover), __func__);
pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
UI_block_emboss_set(pup->block, UI_EMBOSS);
pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 0, MENU_PADDING, style);
pup->slideout = false; // but ? ui_block_is_menu(but->block) : false;
pup->but = but;
uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN);
if (!but) {
/* no button to start from, means we are a popover */
pup->mx = window->eventstate->x;
pup->my = window->eventstate->y;
pup->popover = true;
pup->block->flag |= UI_BLOCK_NO_FLIP;
}
/* some enums reversing is strange, currently we have no good way to
* reverse some enum's but not others, so reverse all so the first menu
* items are always close to the mouse cursor */
else {
if (but->context)
uiLayoutContextCopy(pup->layout, but->context);
}
/* menu is created from a callback */
pup->menu_func = menu_func;
pup->menu_arg = arg;
handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPOVER, pup);
if (!but) {
handle->popup = true;
UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
WM_event_add_mousemove(C);
}
handle->can_refresh = false;
MEM_freeN(pup);
return handle;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Popup Menu API with begin & end
* \{ */
/**
* Only return handler, and set optional title.
* \param block_name: Assigned to uiBlock.name (useful info for debugging).
*/
uiPopover *UI_popover_begin_ex(bContext *C, const char *block_name)
{
uiStyle *style = UI_style_get_dpi();
uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
pup->block = UI_block_begin(C, NULL, block_name, UI_EMBOSS);
pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 0, MENU_PADDING, style);
/* Copied from menus, change if needed. */
uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
/* create in advance so we can let buttons point to retval already */
pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
return pup;
}
uiPopover *UI_popover_begin(bContext *C)
{
return UI_popover_begin_ex(C, __func__);
}
/**
* Setting the button makes the popover open from the button instead of the cursor.
*/
#if 0
void UI_popover_panel_but_set(uiPopover *pup, struct ARegion *butregion, uiBut *but)
{
pup->but = but;
pup->butregion = butregion;
}
#endif
/* set the whole structure to work */
void UI_popover_end(bContext *C, uiPopover *pup)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *menu;
uiBut *but = NULL;
ARegion *butregion = NULL;
pup->popover = true;
pup->mx = window->eventstate->x;
pup->my = window->eventstate->y;
if (pup->but) {
but = pup->but;
butregion = pup->butregion;
}
menu = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPOVER, pup);
menu->popup = true;
UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
WM_event_add_mousemove(C);
menu->can_refresh = false;
MEM_freeN(pup);
}
uiLayout *UI_popover_layout(uiPopover *pup)
{
return pup->layout;
}
/** \} */
/* We may want to support this in futurew */
/* Similar to UI_popup_menu_invoke */
// int UI_popover_panel_invoke(bContext *C, const char *idname, ReportList *reports);

@ -4414,7 +4414,7 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
wt->draw(&wt->wcol, rect, block->flag, block->direction);
else
wt->draw(&wt->wcol, rect, 0, 0);
if (block) {
float draw_color[4];
unsigned char *color = (unsigned char *)wt->wcol.text;

@ -664,6 +664,7 @@ extern StructRNA RNA_TransformSequence;
extern StructRNA RNA_UILayout;
extern StructRNA RNA_UIList;
extern StructRNA RNA_UIPieMenu;
extern StructRNA RNA_uiPopover;
extern StructRNA RNA_UIPopupMenu;
extern StructRNA RNA_UVWarpModifier;
extern StructRNA RNA_UVProjectModifier;

@ -268,6 +268,29 @@ static void rna_uiItemM(uiLayout *layout, bContext *C, const char *menuname, con
uiItemM(layout, C, menuname, name, icon);
}
static void rna_uiItemPopoverPanel(
uiLayout *layout, bContext *C,
int space_type, int region_type, const char *panel_type,
const char *name, const char *text_ctxt,
int translate, int icon, int icon_value)
{
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
if (icon_value && !icon) {
icon = icon_value;
}
uiItemPopoverPanel(layout, C, space_type, region_type, panel_type, name, icon);
}
static void rna_uiItemPopoverPanelFromGroup(
uiLayout *layout, bContext *C,
int space_id, int region_id, const char *context, const char *category)
{
uiItemPopoverPanelFromGroup(layout, C, space_id, region_id, context, category);
}
static void rna_uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
const char *name, const char *text_ctxt, int translate)
{
@ -670,6 +693,29 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
func = RNA_def_function(srna, "popover", "rna_uiItemPopoverPanel");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_enum(func, "space_type", rna_enum_space_type_items, 0, "Space Type", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_enum(func, "region_type", rna_enum_region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "panel_type", NULL, 0, "", "Identifier of the panel");
api_ui_item_common(func);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
func = RNA_def_function(srna, "popover_group", "rna_uiItemPopoverPanelFromGroup");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_enum(func, "space_type", rna_enum_space_type_items, 0, "Space Type", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_enum(func, "region_type", rna_enum_region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "context", NULL, 0, "", "panel type context");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "category", NULL, 0, "", "panel type category");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func = RNA_def_function(srna, "separator", "uiItemS");
RNA_def_function_ui_description(func, "Item. Inserts empty space into the layout between items");

@ -629,6 +629,17 @@ static PointerRNA rna_PopupMenu_layout_get(PointerRNA *ptr)
return rptr;
}
static PointerRNA rna_PopoverMenu_layout_get(PointerRNA *ptr)
{
struct uiPopover *pup = ptr->data;
uiLayout *layout = UI_popover_layout(pup);
PointerRNA rptr;
RNA_pointer_create(ptr->id.data, &RNA_UILayout, layout, &rptr);
return rptr;
}
static PointerRNA rna_PieMenu_layout_get(PointerRNA *ptr)
{
struct uiPieMenu *pie = ptr->data;
@ -1978,6 +1989,11 @@ static void rna_def_popupmenu(BlenderRNA *brna)
rna_def_popup_menu_wrapper(brna, "UIPopupMenu", "uiPopupMenu", "rna_PopupMenu_layout_get");
}
static void rna_def_popovermenu(BlenderRNA *brna)
{
rna_def_popup_menu_wrapper(brna, "UIPopover", "uiPopover", "rna_PopoverMenu_layout_get");
}
static void rna_def_piemenu(BlenderRNA *brna)
{
rna_def_popup_menu_wrapper(brna, "UIPieMenu", "uiPieMenu", "rna_PieMenu_layout_get");
@ -2415,6 +2431,7 @@ void RNA_def_wm(BlenderRNA *brna)
rna_def_event(brna);
rna_def_timer(brna);
rna_def_popupmenu(brna);
rna_def_popovermenu(brna);
rna_def_piemenu(brna);
rna_def_window(brna);
rna_def_windowmanager(brna);

@ -348,6 +348,24 @@ static void rna_PopMenuEnd(bContext *C, PointerRNA *handle)
UI_popup_menu_end(C, handle->data);
}
/* popover wrapper */
static PointerRNA rna_PopoverBegin(bContext *C)
{
PointerRNA r_ptr;
void *data;
data = (void *)UI_popover_begin(C);
RNA_pointer_create(NULL, &RNA_UIPopover, data, &r_ptr);
return r_ptr;
}
static void rna_PopoverEnd(bContext *C, PointerRNA *handle)
{
UI_popover_end(C, handle->data);
}
/* pie menu wrapper */
static PointerRNA rna_PieMenuBegin(bContext *C, const char *title, int icon, PointerRNA *event)
{
@ -541,6 +559,22 @@ void RNA_api_wm(StructRNA *srna)
parm = RNA_def_pointer(func, "menu", "UIPopupMenu", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR);
/* wrap UI_popover_panel_begin */
func = RNA_def_function(srna, "popover_begin__internal", "rna_PopoverBegin");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
/* return */
parm = RNA_def_pointer(func, "menu", "UIPopover", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR);
RNA_def_function_return(func, parm);
/* wrap UI_popover_panel_end */
func = RNA_def_function(srna, "popover_end__internal", "rna_PopoverEnd");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "menu", "UIPopover", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR);
/* wrap uiPieMenuBegin */
func = RNA_def_function(srna, "piemenu_begin__internal", "rna_PieMenuBegin");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);