UI: add use_button option to popovers

This is useful when popovers are launched from operators
instead of as button popover types.
Where the connection between the button and the popover is useful to keep.
This commit is contained in:
Campbell Barton
2019-07-30 10:57:47 +10:00
parent a345f56ce3
commit 369b574fd5
4 changed files with 29 additions and 6 deletions

View File

@@ -151,10 +151,12 @@ class WindowManager(bpy_types.ID):
self, draw_func, *,
ui_units_x=0,
keymap=None,
from_active_button=False,
):
import bpy
popup = self.popover_begin__internal(
ui_units_x=ui_units_x,
from_active_button=from_active_button,
)
try:

View File

@@ -562,7 +562,8 @@ int UI_popover_panel_invoke(struct bContext *C,
bool keep_open,
struct ReportList *reports);
uiPopover *UI_popover_begin(struct bContext *C, int menu_width) ATTR_NONNULL(1);
uiPopover *UI_popover_begin(struct bContext *C, int menu_width, bool from_active_button)
ATTR_NONNULL(1);
void UI_popover_end(struct bContext *C, struct uiPopover *head, struct wmKeyMap *keymap);
struct uiLayout *UI_popover_layout(uiPopover *head);
void UI_popover_once_clear(uiPopover *pup);

View File

@@ -72,6 +72,7 @@ struct uiPopover {
uiBlock *block;
uiLayout *layout;
uiBut *but;
ARegion *butregion;
/* Needed for keymap removal. */
wmWindow *window;
@@ -325,7 +326,7 @@ int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, Rep
block = pup->block;
}
else {
uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x);
uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x, false);
layout = UI_popover_layout(pup);
UI_paneltype_draw(C, pt, layout);
UI_popover_end(C, pup, NULL);
@@ -346,8 +347,11 @@ int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, Rep
/**
* Only return handler, and set optional title.
*
* \param from_active_button: Use the active button for positioning,
* use when the popover is activated from an operator instead of directly from the button.
*/
uiPopover *UI_popover_begin(bContext *C, int ui_size_x)
uiPopover *UI_popover_begin(bContext *C, int ui_size_x, bool from_active_button)
{
uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
if (ui_size_x == 0) {
@@ -355,6 +359,20 @@ uiPopover *UI_popover_begin(bContext *C, int ui_size_x)
}
pup->ui_size_x = ui_size_x;
ARegion *butregion = NULL;
uiBut *but = NULL;
if (from_active_button) {
butregion = CTX_wm_region(C);
but = UI_region_active_but_get(butregion);
if (but == NULL) {
butregion = NULL;
}
}
pup->but = but;
pup->butregion = butregion;
/* Operator context default same as menus, change if needed. */
ui_popover_create_block(C, pup, WM_OP_EXEC_REGION_WIN);
@@ -387,7 +405,7 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
}
handle = ui_popup_block_create(
C, NULL, NULL, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
C, pup->butregion, pup->but, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
/* Add handlers. */
UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);

View File

@@ -471,12 +471,12 @@ static void rna_PopMenuEnd(bContext *C, PointerRNA *handle)
}
/* popover wrapper */
static PointerRNA rna_PopoverBegin(bContext *C, int ui_units_x)
static PointerRNA rna_PopoverBegin(bContext *C, int ui_units_x, bool from_active_button)
{
PointerRNA r_ptr;
void *data;
data = (void *)UI_popover_begin(C, U.widget_unit * ui_units_x);
data = (void *)UI_popover_begin(C, U.widget_unit * ui_units_x, from_active_button);
RNA_pointer_create(NULL, &RNA_UIPopover, data, &r_ptr);
@@ -821,6 +821,8 @@ void RNA_api_wm(StructRNA *srna)
parm = RNA_def_pointer(func, "menu", "UIPopover", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR);
RNA_def_function_return(func, parm);
RNA_def_boolean(
func, "from_active_button", 0, "Use Button", "Use the active button for positioning");
/* wrap UI_popover_end */
func = RNA_def_function(srna, "popover_end__internal", "rna_PopoverEnd");