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:
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user