forked from bartvdbraak/blender
UI: Add support for popups to refresh their layput (D578)
This is needed for popups to chance state once activated, currently it makes use of operators `check` callback, after values are modified, as the file selector does already.
This commit is contained in:
parent
5713d80804
commit
ea2043eb3a
@ -60,6 +60,7 @@ void ED_region_init(struct bContext *C, struct ARegion *ar);
|
|||||||
void ED_region_tag_redraw(struct ARegion *ar);
|
void ED_region_tag_redraw(struct ARegion *ar);
|
||||||
void ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct);
|
void ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct);
|
||||||
void ED_region_tag_redraw_overlay(struct ARegion *ar);
|
void ED_region_tag_redraw_overlay(struct ARegion *ar);
|
||||||
|
void ED_region_tag_refresh_ui(struct ARegion *ar);
|
||||||
void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar);
|
void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar);
|
||||||
void ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, const char *context, int contextnr);
|
void ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, const char *context, int contextnr);
|
||||||
void ED_region_header_init(struct ARegion *ar);
|
void ED_region_header_init(struct ARegion *ar);
|
||||||
|
@ -380,8 +380,10 @@ void uiPupBlockClose(struct bContext *C, uiBlock *block);
|
|||||||
* */
|
* */
|
||||||
|
|
||||||
uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, const char *name, short dt);
|
uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, const char *name, short dt);
|
||||||
|
void uiEndBlock_ex(const struct bContext *C, uiBlock *block, const int xy[2]);
|
||||||
void uiEndBlock(const struct bContext *C, uiBlock *block);
|
void uiEndBlock(const struct bContext *C, uiBlock *block);
|
||||||
void uiDrawBlock(const struct bContext *C, struct uiBlock *block);
|
void uiDrawBlock(const struct bContext *C, struct uiBlock *block);
|
||||||
|
void uiBlockUpdateFromOld(const struct bContext *C, struct uiBlock *block);
|
||||||
|
|
||||||
uiBlock *uiGetBlock(const char *name, struct ARegion *ar);
|
uiBlock *uiGetBlock(const char *name, struct ARegion *ar);
|
||||||
|
|
||||||
|
@ -295,9 +295,8 @@ void ui_bounds_block(uiBlock *block)
|
|||||||
block->safety.ymax = block->rect.ymax + xof;
|
block->safety.ymax = block->rect.ymax + xof;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_centered_bounds_block(const bContext *C, uiBlock *block)
|
static void ui_centered_bounds_block(wmWindow *window, uiBlock *block)
|
||||||
{
|
{
|
||||||
wmWindow *window = CTX_wm_window(C);
|
|
||||||
int xmax, ymax;
|
int xmax, ymax;
|
||||||
int startx, starty;
|
int startx, starty;
|
||||||
int width, height;
|
int width, height;
|
||||||
@ -322,9 +321,9 @@ static void ui_centered_bounds_block(const bContext *C, uiBlock *block)
|
|||||||
ui_bounds_block(block);
|
ui_bounds_block(block);
|
||||||
|
|
||||||
}
|
}
|
||||||
static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBoundsCalc bounds_calc)
|
static void ui_popup_bounds_block(wmWindow *window, uiBlock *block,
|
||||||
|
eBlockBoundsCalc bounds_calc, const int xy[2])
|
||||||
{
|
{
|
||||||
wmWindow *window = CTX_wm_window(C);
|
|
||||||
int startx, starty, endx, endy, width, height, oldwidth, oldheight;
|
int startx, starty, endx, endy, width, height, oldwidth, oldheight;
|
||||||
int oldbounds, xmax, ymax;
|
int oldbounds, xmax, ymax;
|
||||||
const int margin = UI_SCREEN_MARGIN;
|
const int margin = UI_SCREEN_MARGIN;
|
||||||
@ -362,8 +361,8 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound
|
|||||||
|
|
||||||
/* offset block based on mouse position, user offset is scaled
|
/* offset block based on mouse position, user offset is scaled
|
||||||
* along in case we resized the block in ui_text_bounds_block */
|
* along in case we resized the block in ui_text_bounds_block */
|
||||||
startx = window->eventstate->x + block->rect.xmin + (block->mx * width) / oldwidth;
|
startx = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth;
|
||||||
starty = window->eventstate->y + block->rect.ymin + (block->my * height) / oldheight;
|
starty = xy[1] + block->rect.ymin + (block->my * height) / oldheight;
|
||||||
|
|
||||||
if (startx < margin)
|
if (startx < margin)
|
||||||
startx = margin;
|
startx = margin;
|
||||||
@ -1083,29 +1082,50 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiEndBlock(const bContext *C, uiBlock *block)
|
void uiBlockUpdateFromOld(const bContext *C, uiBlock *block)
|
||||||
{
|
{
|
||||||
const bool has_old = (block->oldblock != NULL);
|
uiBut *but_old;
|
||||||
/* avoid searches when old/new lists align */
|
|
||||||
uiBut *but_old = has_old ? block->oldblock->buttons.first : NULL;
|
|
||||||
|
|
||||||
uiBut *but;
|
uiBut *but;
|
||||||
Scene *scene = CTX_data_scene(C);
|
|
||||||
|
|
||||||
|
if (!block->oldblock)
|
||||||
|
return;
|
||||||
|
|
||||||
if (has_old && BLI_listbase_is_empty(&block->oldblock->butstore) == false) {
|
but_old = block->oldblock->buttons.first;
|
||||||
|
|
||||||
|
if (BLI_listbase_is_empty(&block->oldblock->butstore) == false) {
|
||||||
UI_butstore_update(block);
|
UI_butstore_update(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (but = block->buttons.first; but; but = but->next) {
|
||||||
|
if (ui_but_update_from_old_block(C, block, &but, &but_old)) {
|
||||||
|
ui_check_but(but);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block->auto_open = block->oldblock->auto_open;
|
||||||
|
block->auto_open_last = block->oldblock->auto_open_last;
|
||||||
|
block->tooltipdisabled = block->oldblock->tooltipdisabled;
|
||||||
|
copy_v3_v3(ui_block_hsv_get(block),
|
||||||
|
ui_block_hsv_get(block->oldblock));
|
||||||
|
|
||||||
|
block->oldblock = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2])
|
||||||
|
{
|
||||||
|
wmWindow *window = CTX_wm_window(C);
|
||||||
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
uiBut *but;
|
||||||
|
|
||||||
|
BLI_assert(block->active);
|
||||||
|
|
||||||
|
uiBlockUpdateFromOld(C, block);
|
||||||
|
|
||||||
/* inherit flags from 'old' buttons that was drawn here previous, based
|
/* inherit flags from 'old' buttons that was drawn here previous, based
|
||||||
* on matching buttons, we need this to make button event handling non
|
* on matching buttons, we need this to make button event handling non
|
||||||
* blocking, while still allowing buttons to be remade each redraw as it
|
* blocking, while still allowing buttons to be remade each redraw as it
|
||||||
* is expected by blender code */
|
* is expected by blender code */
|
||||||
for (but = block->buttons.first; but; but = but->next) {
|
for (but = block->buttons.first; but; but = but->next) {
|
||||||
if (has_old && ui_but_update_from_old_block(C, block, &but, &but_old)) {
|
|
||||||
ui_check_but(but);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* temp? Proper check for graying out */
|
/* temp? Proper check for graying out */
|
||||||
if (but->optype) {
|
if (but->optype) {
|
||||||
wmOperatorType *ot = but->optype;
|
wmOperatorType *ot = but->optype;
|
||||||
@ -1125,15 +1145,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
|
|||||||
ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
|
ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block->oldblock) {
|
|
||||||
block->auto_open = block->oldblock->auto_open;
|
|
||||||
block->auto_open_last = block->oldblock->auto_open_last;
|
|
||||||
block->tooltipdisabled = block->oldblock->tooltipdisabled;
|
|
||||||
copy_v3_v3(ui_block_hsv_get(block),
|
|
||||||
ui_block_hsv_get(block->oldblock));
|
|
||||||
|
|
||||||
block->oldblock = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle pending stuff */
|
/* handle pending stuff */
|
||||||
if (block->layouts.first) {
|
if (block->layouts.first) {
|
||||||
@ -1159,13 +1171,13 @@ void uiEndBlock(const bContext *C, uiBlock *block)
|
|||||||
ui_text_bounds_block(block, 0.0f);
|
ui_text_bounds_block(block, 0.0f);
|
||||||
break;
|
break;
|
||||||
case UI_BLOCK_BOUNDS_POPUP_CENTER:
|
case UI_BLOCK_BOUNDS_POPUP_CENTER:
|
||||||
ui_centered_bounds_block(C, block);
|
ui_centered_bounds_block(window, block);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* fallback */
|
/* fallback */
|
||||||
case UI_BLOCK_BOUNDS_POPUP_MOUSE:
|
case UI_BLOCK_BOUNDS_POPUP_MOUSE:
|
||||||
case UI_BLOCK_BOUNDS_POPUP_MENU:
|
case UI_BLOCK_BOUNDS_POPUP_MENU:
|
||||||
ui_popup_bounds_block(C, block, block->bounds_type);
|
ui_popup_bounds_block(window, block, block->bounds_type, xy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1179,6 +1191,13 @@ void uiEndBlock(const bContext *C, uiBlock *block)
|
|||||||
block->endblock = 1;
|
block->endblock = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uiEndBlock(const bContext *C, uiBlock *block)
|
||||||
|
{
|
||||||
|
wmWindow *window = CTX_wm_window(C);
|
||||||
|
|
||||||
|
uiEndBlock_ex(C, block, &window->eventstate->x);
|
||||||
|
}
|
||||||
|
|
||||||
/* ************** BLOCK DRAWING FUNCTION ************* */
|
/* ************** BLOCK DRAWING FUNCTION ************* */
|
||||||
|
|
||||||
void ui_fontscale(short *points, float aspect)
|
void ui_fontscale(short *points, float aspect)
|
||||||
@ -2418,6 +2437,7 @@ void uiBlockSetRegion(uiBlock *block, ARegion *region)
|
|||||||
if (oldblock) {
|
if (oldblock) {
|
||||||
oldblock->active = 0;
|
oldblock->active = 0;
|
||||||
oldblock->panel = NULL;
|
oldblock->panel = NULL;
|
||||||
|
oldblock->handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* at the beginning of the list! for dynamical menus/blocks */
|
/* at the beginning of the list! for dynamical menus/blocks */
|
||||||
|
@ -5516,7 +5516,6 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
|
|||||||
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
|
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
|
||||||
|
|
||||||
uiPopupBoundsBlock(block, 6, -50, 26);
|
uiPopupBoundsBlock(block, 6, -50, 26);
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -5561,7 +5560,6 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
|
|||||||
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
|
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
|
||||||
|
|
||||||
uiPopupBoundsBlock(block, 6, -50, 26);
|
uiPopupBoundsBlock(block, 6, -50, 26);
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -7762,6 +7760,8 @@ static int ui_handle_menu_event(
|
|||||||
sub_v2_v2v2_int(mdiff, &event->x, menu->grab_xy_prev);
|
sub_v2_v2v2_int(mdiff, &event->x, menu->grab_xy_prev);
|
||||||
copy_v2_v2_int(menu->grab_xy_prev, &event->x);
|
copy_v2_v2_int(menu->grab_xy_prev, &event->x);
|
||||||
|
|
||||||
|
add_v2_v2v2_int(menu->popup_create_vars.event_xy, menu->popup_create_vars.event_xy, mdiff);
|
||||||
|
|
||||||
ui_popup_translate(C, ar, mdiff);
|
ui_popup_translate(C, ar, mdiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8414,10 +8414,13 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
|
|||||||
static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
|
static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
|
||||||
{
|
{
|
||||||
uiPopupBlockHandle *menu = userdata;
|
uiPopupBlockHandle *menu = userdata;
|
||||||
|
struct ARegion *menu_region;
|
||||||
/* we block all events, this is modal interaction, except for drop events which is described below */
|
/* we block all events, this is modal interaction, except for drop events which is described below */
|
||||||
int retval = WM_UI_HANDLER_BREAK;
|
int retval = WM_UI_HANDLER_BREAK;
|
||||||
|
|
||||||
|
menu_region = CTX_wm_menu(C);
|
||||||
|
CTX_wm_menu_set(C, menu->region);
|
||||||
|
|
||||||
if (event->type == EVT_DROP) {
|
if (event->type == EVT_DROP) {
|
||||||
/* if we're handling drop event we'll want it to be handled by popup callee as well,
|
/* if we're handling drop event we'll want it to be handled by popup callee as well,
|
||||||
* so it'll be possible to perform such operations as opening .blend files by dropping
|
* so it'll be possible to perform such operations as opening .blend files by dropping
|
||||||
@ -8465,6 +8468,8 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
|
|||||||
/* delayed apply callbacks */
|
/* delayed apply callbacks */
|
||||||
ui_apply_but_funcs_after(C);
|
ui_apply_but_funcs_after(C);
|
||||||
|
|
||||||
|
CTX_wm_region_set(C, menu_region);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,6 +428,19 @@ struct uiKeyNavLock {
|
|||||||
int event_xy[2];
|
int event_xy[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uiBlock * (*uiBlockHandleCreateFunc)(struct bContext *C, struct uiPopupBlockHandle *handle, void *arg1);
|
||||||
|
|
||||||
|
struct uiPopupBlockCreate {
|
||||||
|
uiBlockCreateFunc create_func;
|
||||||
|
uiBlockHandleCreateFunc handle_create_func;
|
||||||
|
void *arg;
|
||||||
|
|
||||||
|
int event_xy[2];
|
||||||
|
|
||||||
|
/* when popup is initialized from a button */
|
||||||
|
ARegion *butregion;
|
||||||
|
};
|
||||||
|
|
||||||
struct uiPopupBlockHandle {
|
struct uiPopupBlockHandle {
|
||||||
/* internal */
|
/* internal */
|
||||||
struct ARegion *region;
|
struct ARegion *region;
|
||||||
@ -442,6 +455,9 @@ struct uiPopupBlockHandle {
|
|||||||
void (*cancel_func)(struct bContext *C, void *arg);
|
void (*cancel_func)(struct bContext *C, void *arg);
|
||||||
void *popup_arg;
|
void *popup_arg;
|
||||||
|
|
||||||
|
/* store data for refreshing popups */
|
||||||
|
struct uiPopupBlockCreate popup_create_vars;
|
||||||
|
|
||||||
struct wmTimer *scrolltimer;
|
struct wmTimer *scrolltimer;
|
||||||
|
|
||||||
struct uiKeyNavLock keynav_state;
|
struct uiKeyNavLock keynav_state;
|
||||||
@ -496,7 +512,8 @@ bool ui_searchbox_apply(uiBut *but, struct ARegion *ar);
|
|||||||
void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
|
void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
|
||||||
void ui_but_search_test(uiBut *but);
|
void ui_but_search_test(uiBut *but);
|
||||||
|
|
||||||
typedef uiBlock * (*uiBlockHandleCreateFunc)(struct bContext *C, struct uiPopupBlockHandle *handle, void *arg1);
|
uiBlock *ui_popup_block_refresh(struct bContext *C, uiPopupBlockHandle *handle,
|
||||||
|
ARegion *butregion, uiBut *but);
|
||||||
|
|
||||||
uiPopupBlockHandle *ui_popup_block_create(struct bContext *C, struct ARegion *butregion, uiBut *but,
|
uiPopupBlockHandle *ui_popup_block_create(struct bContext *C, struct ARegion *butregion, uiBut *but,
|
||||||
uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
|
uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
|
||||||
|
@ -2983,6 +2983,8 @@ void uiBlockLayoutResolve(uiBlock *block, int *x, int *y)
|
|||||||
{
|
{
|
||||||
uiLayoutRoot *root;
|
uiLayoutRoot *root;
|
||||||
|
|
||||||
|
BLI_assert(block->active);
|
||||||
|
|
||||||
if (x) *x = 0;
|
if (x) *x = 0;
|
||||||
if (y) *y = 0;
|
if (y) *y = 0;
|
||||||
|
|
||||||
|
@ -1421,6 +1421,15 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
|
|||||||
{
|
{
|
||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
|
|
||||||
|
if (ar->do_draw & RGN_DRAW_REFRESH_UI) {
|
||||||
|
uiBlock *block_next;
|
||||||
|
ar->do_draw &= ~RGN_DRAW_REFRESH_UI;
|
||||||
|
for (block = ar->uiblocks.first; block; block = block_next) {
|
||||||
|
block_next = block->next;
|
||||||
|
ui_popup_block_refresh((bContext *)C, block->handle, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (block = ar->uiblocks.first; block; block = block->next)
|
for (block = ar->uiblocks.first; block; block = block->next)
|
||||||
uiDrawBlock(C, block);
|
uiDrawBlock(C, block);
|
||||||
}
|
}
|
||||||
@ -1502,42 +1511,50 @@ void ui_popup_block_scrolltest(uiBlock *block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but,
|
static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
|
||||||
uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
|
|
||||||
void *arg)
|
|
||||||
{
|
{
|
||||||
|
ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region);
|
||||||
|
|
||||||
|
if (handle->scrolltimer)
|
||||||
|
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), handle->scrolltimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called for creatign new popups and refreshing existing ones.
|
||||||
|
*/
|
||||||
|
uiBlock *ui_popup_block_refresh(
|
||||||
|
bContext *C, uiPopupBlockHandle *handle,
|
||||||
|
ARegion *butregion, uiBut *but)
|
||||||
|
{
|
||||||
|
const int width = UI_ThemeMenuShadowWidth();
|
||||||
wmWindow *window = CTX_wm_window(C);
|
wmWindow *window = CTX_wm_window(C);
|
||||||
static ARegionType type;
|
ARegion *ar = handle->region;
|
||||||
ARegion *ar;
|
|
||||||
|
uiBlockCreateFunc create_func = handle->popup_create_vars.create_func;
|
||||||
|
uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func;
|
||||||
|
void *arg = handle->popup_create_vars.arg;
|
||||||
|
|
||||||
|
uiBlock *block_old = ar->uiblocks.first;
|
||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
uiPopupBlockHandle *handle;
|
|
||||||
uiSafetyRct *saferct;
|
|
||||||
int width = UI_ThemeMenuShadowWidth();
|
|
||||||
|
|
||||||
/* create handle */
|
#ifdef DEBUG
|
||||||
handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
|
wmEvent *event_back = window->eventstate;
|
||||||
|
#endif
|
||||||
/* store context for operator */
|
|
||||||
handle->ctx_area = CTX_wm_area(C);
|
|
||||||
handle->ctx_region = CTX_wm_region(C);
|
|
||||||
|
|
||||||
/* create area region */
|
|
||||||
ar = ui_add_temporary_region(CTX_wm_screen(C));
|
|
||||||
handle->region = ar;
|
|
||||||
|
|
||||||
memset(&type, 0, sizeof(ARegionType));
|
|
||||||
type.draw = ui_block_region_draw;
|
|
||||||
type.regionid = RGN_TYPE_TEMPORARY;
|
|
||||||
ar->type = &type;
|
|
||||||
|
|
||||||
UI_add_region_handlers(&ar->handlers);
|
|
||||||
|
|
||||||
/* create ui block */
|
/* create ui block */
|
||||||
if (create_func)
|
if (create_func)
|
||||||
block = create_func(C, handle->region, arg);
|
block = create_func(C, ar, arg);
|
||||||
else
|
else
|
||||||
block = handle_create_func(C, handle, arg);
|
block = handle_create_func(C, handle, arg);
|
||||||
|
|
||||||
|
/* callbacks _must_ leave this for us, otherwise we can't call uiBlockUpdateFromOld */
|
||||||
|
BLI_assert(!block->endblock);
|
||||||
|
|
||||||
|
/* ensure we don't use mouse coords here! */
|
||||||
|
#ifdef DEBUG
|
||||||
|
window->eventstate = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (block->handle) {
|
if (block->handle) {
|
||||||
memcpy(block->handle, handle, sizeof(uiPopupBlockHandle));
|
memcpy(block->handle, handle, sizeof(uiPopupBlockHandle));
|
||||||
MEM_freeN(handle);
|
MEM_freeN(handle);
|
||||||
@ -1560,8 +1577,11 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
|
|||||||
|
|
||||||
block->flag |= UI_BLOCK_LOOP;
|
block->flag |= UI_BLOCK_LOOP;
|
||||||
|
|
||||||
|
/* defer this until blocks are translated (below) */
|
||||||
|
block->oldblock = NULL;
|
||||||
|
|
||||||
if (!block->endblock)
|
if (!block->endblock)
|
||||||
uiEndBlock(C, block);
|
uiEndBlock_ex(C, block, handle->popup_create_vars.event_xy);
|
||||||
|
|
||||||
/* if this is being created from a button */
|
/* if this is being created from a button */
|
||||||
if (but) {
|
if (but) {
|
||||||
@ -1570,6 +1590,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
|
|||||||
handle->direction = block->direction;
|
handle->direction = block->direction;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
uiSafetyRct *saferct;
|
||||||
/* keep a list of these, needed for pulldown menus */
|
/* keep a list of these, needed for pulldown menus */
|
||||||
saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
|
saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
|
||||||
saferct->safety = block->safety;
|
saferct->safety = block->safety;
|
||||||
@ -1589,12 +1610,18 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
|
|||||||
|
|
||||||
ui_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);
|
ui_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);
|
||||||
|
|
||||||
/* adds subwindow */
|
if (block_old) {
|
||||||
ED_region_init(C, ar);
|
block->oldblock = block_old;
|
||||||
|
uiBlockUpdateFromOld(C, block);
|
||||||
|
uiFreeInactiveBlocks(C, &ar->uiblocks);
|
||||||
|
}
|
||||||
|
|
||||||
/* checks which buttons are visible, sets flags to prevent draw (do after region init) */
|
/* checks which buttons are visible, sets flags to prevent draw (do after region init) */
|
||||||
ui_popup_block_scrolltest(block);
|
ui_popup_block_scrolltest(block);
|
||||||
|
|
||||||
|
/* adds subwindow */
|
||||||
|
ED_region_init(C, ar);
|
||||||
|
|
||||||
/* get winmat now that we actually have the subwindow */
|
/* get winmat now that we actually have the subwindow */
|
||||||
wmSubWindowSet(window, ar->swinid);
|
wmSubWindowSet(window, ar->swinid);
|
||||||
|
|
||||||
@ -1603,15 +1630,59 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
|
|||||||
/* notify change and redraw */
|
/* notify change and redraw */
|
||||||
ED_region_tag_redraw(ar);
|
ED_region_tag_redraw(ar);
|
||||||
|
|
||||||
|
ED_region_update_rect(C, ar);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
window->eventstate = event_back;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but,
|
||||||
|
uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
wmWindow *window = CTX_wm_window(C);
|
||||||
|
static ARegionType type;
|
||||||
|
ARegion *ar;
|
||||||
|
uiBlock *block;
|
||||||
|
uiPopupBlockHandle *handle;
|
||||||
|
|
||||||
|
/* create handle */
|
||||||
|
handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
|
||||||
|
|
||||||
|
/* store context for operator */
|
||||||
|
handle->ctx_area = CTX_wm_area(C);
|
||||||
|
handle->ctx_region = CTX_wm_region(C);
|
||||||
|
|
||||||
|
/* store vars to refresh popup (RGN_DRAW_REFRESH_UI) */
|
||||||
|
handle->popup_create_vars.create_func = create_func;
|
||||||
|
handle->popup_create_vars.handle_create_func = handle_create_func;
|
||||||
|
handle->popup_create_vars.arg = arg;
|
||||||
|
handle->popup_create_vars.butregion = but ? butregion : NULL;
|
||||||
|
copy_v2_v2_int(handle->popup_create_vars.event_xy, &window->eventstate->x);
|
||||||
|
|
||||||
|
/* create area region */
|
||||||
|
ar = ui_add_temporary_region(CTX_wm_screen(C));
|
||||||
|
handle->region = ar;
|
||||||
|
|
||||||
|
memset(&type, 0, sizeof(ARegionType));
|
||||||
|
type.draw = ui_block_region_draw;
|
||||||
|
type.regionid = RGN_TYPE_TEMPORARY;
|
||||||
|
ar->type = &type;
|
||||||
|
|
||||||
|
UI_add_region_handlers(&ar->handlers);
|
||||||
|
|
||||||
|
block = ui_popup_block_refresh(C, handle, butregion, but);
|
||||||
|
handle = block->handle;
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
|
void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
|
||||||
{
|
{
|
||||||
ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region);
|
ui_popup_block_remove(C, handle);
|
||||||
|
|
||||||
if (handle->scrolltimer)
|
|
||||||
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), handle->scrolltimer);
|
|
||||||
|
|
||||||
MEM_freeN(handle);
|
MEM_freeN(handle);
|
||||||
}
|
}
|
||||||
@ -2278,8 +2349,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||||||
if (pup->slideout)
|
if (pup->slideout)
|
||||||
uiBlockSetDirection(block, UI_RIGHT);
|
uiBlockSetDirection(block, UI_RIGHT);
|
||||||
|
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
return pup->block;
|
return pup->block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,6 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
|
|||||||
|
|
||||||
uiBoundsBlock(block, 0.3f * U.widget_unit);
|
uiBoundsBlock(block, 0.3f * U.widget_unit);
|
||||||
uiBlockSetDirection(block, UI_DOWN);
|
uiBlockSetDirection(block, UI_DOWN);
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
/* give search-field focus */
|
/* give search-field focus */
|
||||||
uiButSetFocusOnEnter(win, but);
|
uiButSetFocusOnEnter(win, but);
|
||||||
|
@ -472,6 +472,7 @@ void ED_region_tag_redraw(ARegion *ar)
|
|||||||
* but python scripts can cause this to happen indirectly */
|
* but python scripts can cause this to happen indirectly */
|
||||||
if (ar && !(ar->do_draw & RGN_DRAWING)) {
|
if (ar && !(ar->do_draw & RGN_DRAWING)) {
|
||||||
/* zero region means full region redraw */
|
/* zero region means full region redraw */
|
||||||
|
ar->do_draw &= ~RGN_DRAW_PARTIAL; /* just incase */
|
||||||
ar->do_draw = RGN_DRAW;
|
ar->do_draw = RGN_DRAW;
|
||||||
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
|
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
|
||||||
}
|
}
|
||||||
@ -483,6 +484,13 @@ void ED_region_tag_redraw_overlay(ARegion *ar)
|
|||||||
ar->do_draw_overlay = RGN_DRAW;
|
ar->do_draw_overlay = RGN_DRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ED_region_tag_refresh_ui(ARegion *ar)
|
||||||
|
{
|
||||||
|
if (ar) {
|
||||||
|
ar->do_draw |= RGN_DRAW_REFRESH_UI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ED_region_tag_redraw_partial(ARegion *ar, rcti *rct)
|
void ED_region_tag_redraw_partial(ARegion *ar, rcti *rct)
|
||||||
{
|
{
|
||||||
if (ar && !(ar->do_draw & RGN_DRAWING)) {
|
if (ar && !(ar->do_draw & RGN_DRAWING)) {
|
||||||
|
@ -971,7 +971,6 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
|
|||||||
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
||||||
|
|
||||||
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
// uiButActiveOnly(C, ar, block, but); XXX using this here makes Blender hang - investigate
|
// uiButActiveOnly(C, ar, block, but); XXX using this here makes Blender hang - investigate
|
||||||
wm_event_init_from_window(win, &event);
|
wm_event_init_from_window(win, &event);
|
||||||
|
@ -385,7 +385,13 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
|
|||||||
ED_undo_pop_op(C, op);
|
ED_undo_pop_op(C, op);
|
||||||
|
|
||||||
if (op->type->check) {
|
if (op->type->check) {
|
||||||
op->type->check(C, op); /* ignore return value since its running again anyway */
|
if (op->type->check(C, op)) {
|
||||||
|
/* check for popup and re-layout buttons */
|
||||||
|
ARegion *ar_menu = CTX_wm_menu(C);
|
||||||
|
if (ar_menu) {
|
||||||
|
ED_region_tag_refresh_ui(ar_menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = WM_operator_repeat(C, op);
|
retval = WM_operator_repeat(C, op);
|
||||||
|
@ -383,6 +383,6 @@ enum {
|
|||||||
#define RGN_DRAW 1
|
#define RGN_DRAW 1
|
||||||
#define RGN_DRAW_PARTIAL 2
|
#define RGN_DRAW_PARTIAL 2
|
||||||
#define RGN_DRAWING 4
|
#define RGN_DRAWING 4
|
||||||
|
#define RGN_DRAW_REFRESH_UI 8 /* re-create uiBlock's where possible */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1086,7 +1086,6 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
|
|||||||
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
||||||
|
|
||||||
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
wm_event_init_from_window(win, &event);
|
wm_event_init_from_window(win, &event);
|
||||||
event.type = EVT_BUT_OPEN;
|
event.type = EVT_BUT_OPEN;
|
||||||
@ -1427,7 +1426,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uiPopupBoundsBlock(block, 4, 0, 0);
|
uiPopupBoundsBlock(block, 4, 0, 0);
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -1462,7 +1460,11 @@ static void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
|
|||||||
wmOperator *op = op_ptr;
|
wmOperator *op = op_ptr;
|
||||||
if (op->type->check) {
|
if (op->type->check) {
|
||||||
if (op->type->check(C, op)) {
|
if (op->type->check(C, op)) {
|
||||||
/* refresh */
|
/* check for popup and re-layout buttons */
|
||||||
|
ARegion *ar_menu = CTX_wm_menu(C);
|
||||||
|
if (ar_menu) {
|
||||||
|
ED_region_tag_refresh_ui(ar_menu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1507,7 +1509,6 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
|
|||||||
|
|
||||||
/* center around the mouse */
|
/* center around the mouse */
|
||||||
uiPopupBoundsBlock(block, 4, data->width / -2, data->height / 2);
|
uiPopupBoundsBlock(block, 4, data->width / -2, data->height / 2);
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -1530,7 +1531,6 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
|
|||||||
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
|
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
|
||||||
|
|
||||||
uiPopupBoundsBlock(block, 4, 0, 0);
|
uiPopupBoundsBlock(block, 4, 0, 0);
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -1929,7 +1929,6 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
|
|||||||
uiItemL(col, "", ICON_NONE);
|
uiItemL(col, "", ICON_NONE);
|
||||||
|
|
||||||
uiCenteredBoundsBlock(block, 0);
|
uiCenteredBoundsBlock(block, 0);
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -1971,7 +1970,6 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
|
|||||||
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
||||||
|
|
||||||
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
||||||
uiEndBlock(C, block);
|
|
||||||
|
|
||||||
wm_event_init_from_window(win, &event);
|
wm_event_init_from_window(win, &event);
|
||||||
event.type = EVT_BUT_OPEN;
|
event.type = EVT_BUT_OPEN;
|
||||||
|
Loading…
Reference in New Issue
Block a user