Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/include/UI_interface.h22
-rw-r--r--source/blender/editors/interface/interface_handlers.c189
-rw-r--r--source/blender/editors/interface/interface_regions.c198
-rw-r--r--source/blender/windowmanager/WM_api.h7
-rw-r--r--source/blender/windowmanager/WM_types.h4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c11
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c21
-rw-r--r--source/blender/windowmanager/wm_event_system.h1
8 files changed, 205 insertions, 248 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 5b0f0bbc2bf..fffc161255f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -185,20 +185,31 @@ void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, fl
/* Popup Menu's */
typedef struct uiMenuBlockHandle {
+ /* internal */
struct ARegion *region;
+ int towardsx, towardsy;
+ double towardstime;
+ int dotowards;
+
+ int popup;
+ void (*popup_func)(struct bContext *C, void *arg, int event);
+ void *popup_arg;
+
+ /* return values */
int butretval;
int menuretval;
-
float retvalue;
float retvec[3];
} uiMenuBlockHandle;
typedef uiBlock* (*uiBlockFuncFP)(struct bContext *C, struct uiMenuBlockHandle *handle, void *arg1);
+typedef void (*uiPupmenuFunc)(struct bContext *C, void *arg, int event);
extern void pupmenu_set_active(int val);
-extern uiMenuBlockHandle *pupmenu_col(struct bContext *C, char *instr, int mx, int my, int maxrow);
-extern uiMenuBlockHandle *pupmenu(struct bContext *C, char *instr, int mx, int my);
-extern void pupmenu_free(struct bContext *C, uiMenuBlockHandle *handle);
+extern void pupmenu_col(struct bContext *C, char *instr, int mx, int my, int maxrow, uiPupmenuFunc func, void *arg);
+extern void pupmenu(struct bContext *C, char *instr, int mx, int my, uiPupmenuFunc func, void *arg);
+
+void okee_operator(struct bContext *C, char *opname, char *str, ...);
/* Block */
@@ -354,6 +365,7 @@ void autocomplete_end(AutoComplete *autocpl, char *autoname);
/* Handlers for regions with UI blocks */
void UI_add_region_handlers(struct ListBase *handlers);
+void UI_add_popup_handlers(struct ListBase *handlers, uiMenuBlockHandle *menu);
/* Module initialization and exit */
@@ -361,7 +373,5 @@ void UI_init(void);
void UI_init_userdef(void);
void UI_exit(void);
-void uiTestRegion(const struct bContext *C); /* XXX 2.50 temporary test */
-
#endif /* UI_INTERFACE_H */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 144e8490661..994fdc18d1a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -82,14 +82,6 @@ typedef enum uiHandleButtonState {
BUTTON_STATE_EXIT
} uiHandleButtonState;
-typedef struct uiHandleMenuData {
- uiMenuBlockHandle *handle;
-
- int towardsx, towardsy;
- double towardstime;
- int dotowards;
-} uiHandleMenuData;
-
typedef struct uiHandleButtonData {
wmWindow *window;
ARegion *region;
@@ -126,7 +118,7 @@ typedef struct uiHandleButtonData {
CBData *dragcbd;
/* menu open */
- uiHandleMenuData *menu;
+ uiMenuBlockHandle *menu;
int menuretval;
/* post activate */
@@ -151,7 +143,9 @@ typedef struct uiAfterFunc {
} uiAfterFunc;
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
-static int ui_handler_window(bContext *C, wmEvent *event);
+static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata);
+static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata);
+static void ui_handler_remove_popup(bContext *C, void *userdata);
/* ********************** button apply/revert ************************/
@@ -1393,8 +1387,9 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data
}
if(func) {
- data->menu= MEM_callocN(sizeof(uiHandleMenuData), "uiHandleMenuData");
- data->menu->handle= ui_menu_block_create(C, data->region, but, func, arg);
+ data->menu= ui_menu_block_create(C, data->region, but, func, arg);
+ if(but->block->handle)
+ data->menu->popup= but->block->handle->popup;
}
/* this makes adjacent blocks auto open from now on */
@@ -1411,8 +1406,7 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
}
if(data->menu) {
- ui_menu_block_free(C, data->menu->handle);
- MEM_freeN(data->menu);
+ ui_menu_block_free(C, data->menu);
data->menu= NULL;
}
}
@@ -2649,6 +2643,9 @@ static void ui_blocks_set_tooltips(ARegion *ar, int enable)
{
uiBlock *block;
+ if(!ar)
+ return;
+
/* we disabled buttons when when they were already shown, and
* re-enable them on mouse move */
for(block=ar->uiblocks.first; block; block=block->next)
@@ -2786,14 +2783,17 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
data->flashtimer= NULL;
}
- /* add a blocking ui handler at the window handler for blocking, modal states */
- if(button_modal_state(state)) {
- if(!button_modal_state(data->state))
- WM_event_add_ui_handler(C, &data->window->handlers, ui_handler_window, NULL);
- }
- else {
- if(button_modal_state(data->state))
- WM_event_remove_ui_handler(&data->window->handlers);
+ /* add a blocking ui handler at the window handler for blocking, modal states
+ * but not for popups, because we already have a window level handler*/
+ if(!(but->block->handle && but->block->handle->popup)) {
+ if(button_modal_state(state)) {
+ if(!button_modal_state(data->state))
+ WM_event_add_ui_handler(C, &data->window->handlers, ui_handler_region_menu, NULL, data);
+ }
+ else {
+ if(button_modal_state(data->state))
+ WM_event_remove_ui_handler(&data->window->handlers, ui_handler_region_menu, NULL, data);
+ }
}
data->state= state;
@@ -2840,20 +2840,20 @@ static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *b
if(data->state != BUTTON_STATE_EXIT)
button_activate_state(C, but, BUTTON_STATE_EXIT);
+ /* apply the button action or value */
+ ui_apply_button(C, block, but, data, 0);
+
/* if this button is in a menu, this will set the button return
* value to the button value and the menu return value to ok, the
* menu return value will be picked up and the menu will close */
if(block->handle && !(block->flag & UI_BLOCK_KEEP_OPEN) && !data->cancel) {
- uiMenuBlockHandle *handle;
+ uiMenuBlockHandle *menu;
- handle= block->handle;
- handle->butretval= data->retval;
- handle->menuretval= UI_RETURN_OK;
+ menu= block->handle;
+ menu->butretval= data->retval;
+ menu->menuretval= UI_RETURN_OK;
}
- /* apply the button action or value */
- ui_apply_button(C, block, but, data, 0);
-
/* disable tooltips until mousemove */
ui_blocks_set_tooltips(data->region, 0);
@@ -3070,27 +3070,27 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
static void ui_handle_button_closed_submenu(bContext *C, uiBut *but)
{
uiHandleButtonData *data;
- uiMenuBlockHandle *handle;
+ uiMenuBlockHandle *menu;
data= but->active;
- handle= data->menu->handle;
+ menu= data->menu;
/* copy over return values from the closing menu */
- if(handle->menuretval == UI_RETURN_OK) {
+ if(menu->menuretval == UI_RETURN_OK) {
if(but->type == COL)
- VECCOPY(data->vec, handle->retvec)
+ VECCOPY(data->vec, menu->retvec)
else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
- data->value= handle->retvalue;
+ data->value= menu->retvalue;
}
/* now change button state or exit, which will close the submenu */
- if(ELEM(handle->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) {
- if(handle->menuretval != UI_RETURN_OK)
+ if(ELEM(menu->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) {
+ if(menu->menuretval != UI_RETURN_OK)
data->cancel= 1;
button_activate_exit(C, data, but, 1);
}
- else if(handle->menuretval == UI_RETURN_OUT)
+ else if(menu->menuretval == UI_RETURN_OUT)
button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
}
@@ -3149,7 +3149,7 @@ static uiBut *ui_but_last(uiBlock *block)
* - only for 1 second
*/
-static void ui_mouse_motion_towards_init(uiHandleMenuData *menu, int mx, int my)
+static void ui_mouse_motion_towards_init(uiMenuBlockHandle *menu, int mx, int my)
{
if(!menu->dotowards) {
menu->dotowards= 1;
@@ -3159,7 +3159,7 @@ static void ui_mouse_motion_towards_init(uiHandleMenuData *menu, int mx, int my)
}
}
-static int ui_mouse_motion_towards_check(uiBlock *block, uiHandleMenuData *menu, int mx, int my)
+static int ui_mouse_motion_towards_check(uiBlock *block, uiMenuBlockHandle *menu, int mx, int my)
{
int fac, dx, dy, domx, domy;
@@ -3213,17 +3213,15 @@ static int ui_mouse_motion_towards_check(uiBlock *block, uiHandleMenuData *menu,
return menu->dotowards;
}
-int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, int topmenu)
+int ui_handle_menu_event(bContext *C, wmEvent *event, uiMenuBlockHandle *menu, int topmenu)
{
ARegion *ar;
uiBlock *block;
uiBut *but, *bt;
- uiMenuBlockHandle *handle;
int inside, act, count, mx, my, retval;
- ar= menu->handle->region;
+ ar= menu->region;
block= ar->uiblocks.first;
- handle= menu->handle;
act= 0;
retval= WM_UI_HANDLER_CONTINUE;
@@ -3248,7 +3246,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in
case LEFTARROWKEY:
if(event->val && (block->flag & UI_BLOCK_LOOP))
if(BLI_countlist(&block->saferct) > 0)
- handle->menuretval= UI_RETURN_OUT;
+ menu->menuretval= UI_RETURN_OUT;
retval= WM_UI_HANDLER_BREAK;
break;
@@ -3372,18 +3370,19 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in
if(ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) && event->val)
if(saferct && !BLI_in_rctf(&saferct->parent, event->x, event->y))
- handle->menuretval= UI_RETURN_OK;
+ menu->menuretval= UI_RETURN_OK;
}
- if(handle->menuretval);
+ if(menu->menuretval);
else if(event->type==ESCKEY && event->val) {
/* esc cancels this and all preceding menus */
- handle->menuretval= UI_RETURN_CANCEL;
+ menu->menuretval= UI_RETURN_CANCEL;
}
else if(ELEM(event->type, RETKEY, PADENTER) && event->val) {
- /* enter will always close this block, but note that the event
- * can still get pass through so the button is executed */
- handle->menuretval= UI_RETURN_OK;
+ /* enter will always close this block, but we let the event
+ * get handled by the button if it is activated */
+ if(!ui_but_find_activated(ar))
+ menu->menuretval= UI_RETURN_OK;
}
else {
ui_mouse_motion_towards_check(block, menu, mx, my);
@@ -3407,7 +3406,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in
/* strict check, and include the parent rect */
if(!menu->dotowards && !saferct)
- handle->menuretval= (block->flag & UI_BLOCK_KEEP_OPEN)? UI_RETURN_OK: UI_RETURN_OUT;
+ menu->menuretval= (block->flag & UI_BLOCK_KEEP_OPEN)? UI_RETURN_OK: UI_RETURN_OUT;
else if(menu->dotowards && event->type==MOUSEMOVE)
retval= WM_UI_HANDLER_BREAK;
}
@@ -3417,7 +3416,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in
/* if we are inside the region and didn't handle the event yet, lets
* pass it on to buttons inside this region */
- if((inside && !handle->menuretval && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) {
+ if((inside && !menu->menuretval && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) {
but= ui_but_find_activated(ar);
if(but)
@@ -3429,7 +3428,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in
/* if we set a menu return value, ensure we continue passing this on to
* lower menus and buttons, so always set continue then, and if we are
* inside the region otherwise, ensure we swallow the event */
- if(handle->menuretval)
+ if(menu->menuretval)
return WM_UI_HANDLER_CONTINUE;
else if(inside)
return WM_UI_HANDLER_BREAK;
@@ -3437,29 +3436,27 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in
return retval;
}
-static int ui_handle_menu_closed_submenu(bContext *C, uiHandleMenuData *menu)
+static int ui_handle_menu_closed_submenu(bContext *C, uiMenuBlockHandle *menu)
{
ARegion *ar;
uiBut *but;
uiBlock *block;
uiHandleButtonData *data;
- uiMenuBlockHandle *handle, *subhandle;
+ uiMenuBlockHandle *submenu;
- ar= menu->handle->region;
+ ar= menu->region;
block= ar->uiblocks.first;
- handle= menu->handle;
but= ui_but_find_activated(ar);
data= but->active;
- subhandle= data->menu->handle;
- if(subhandle->menuretval) {
+ if(submenu->menuretval) {
/* first decide if we want to close our own menu cascading, if
* so pass on the sub menu return value to our own menu handle */
- if(ELEM(subhandle->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) {
+ if(ELEM(submenu->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) {
if(!(block->flag & UI_BLOCK_KEEP_OPEN)) {
- handle->menuretval= subhandle->menuretval;
- handle->butretval= data->retval;
+ menu->menuretval= submenu->menuretval;
+ menu->butretval= data->retval;
}
}
@@ -3468,21 +3465,21 @@ static int ui_handle_menu_closed_submenu(bContext *C, uiHandleMenuData *menu)
ui_handle_button_closed_submenu(C, but);
}
- if(handle->menuretval)
+ if(menu->menuretval)
return WM_UI_HANDLER_CONTINUE;
else
return WM_UI_HANDLER_BREAK;
}
-static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiHandleMenuData *menu)
+static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiMenuBlockHandle *menu)
{
uiBut *but;
uiHandleButtonData *data;
- uiHandleMenuData *submenu;
+ uiMenuBlockHandle *submenu;
int retval= WM_UI_HANDLER_CONTINUE;
/* check if we have a submenu, and handle events for it first */
- but= ui_but_find_activated(menu->handle->region);
+ but= ui_but_find_activated(menu->region);
data= (but)? but->active: NULL;
submenu= (data)? data->menu: NULL;
@@ -3491,7 +3488,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiHandleMenuDa
/* now handle events for our own menu */
if(retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- if(submenu && submenu->handle->menuretval)
+ if(submenu && submenu->menuretval)
retval= ui_handle_menu_closed_submenu(C, menu);
else
retval= ui_handle_menu_event(C, event, menu, (submenu == NULL));
@@ -3502,7 +3499,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiHandleMenuDa
/* *************** UI event handlers **************** */
-static int ui_handler_region(bContext *C, wmEvent *event)
+static int ui_handler_region(bContext *C, wmEvent *event, void *userdata)
{
ARegion *ar;
uiBut *but;
@@ -3533,7 +3530,7 @@ static int ui_handler_region(bContext *C, wmEvent *event)
return retval;
}
-static void ui_handler_remove_region(bContext *C)
+static void ui_handler_remove_region(bContext *C, void *userdata)
{
bScreen *sc;
ARegion *ar;
@@ -3553,7 +3550,7 @@ static void ui_handler_remove_region(bContext *C)
ui_apply_but_funcs_after(C);
}
-static int ui_handler_window(bContext *C, wmEvent *event)
+static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata)
{
ARegion *ar;
uiBut *but;
@@ -3563,11 +3560,10 @@ static int ui_handler_window(bContext *C, wmEvent *event)
/* here we handle buttons at the window level, modal, for example
* while number sliding, text editing, or when a menu block is open */
ar= C->region;
-
- /* handle activated button events */
but= ui_but_find_activated(ar);
if(but) {
+ /* handle activated button events */
data= but->active;
if(data->state == BUTTON_STATE_MENU_OPEN) {
@@ -3577,7 +3573,7 @@ static int ui_handler_window(bContext *C, wmEvent *event)
/* handle events for the activated button */
if(retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- if(data->menu->handle->menuretval)
+ if(data->menu->menuretval)
ui_handle_button_closed_submenu(C, but);
else
ui_handle_button_event(C, event, but);
@@ -3600,9 +3596,52 @@ static int ui_handler_window(bContext *C, wmEvent *event)
return WM_UI_HANDLER_BREAK;
}
+static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
+{
+ uiMenuBlockHandle *menu= userdata;
+
+ ui_handle_menus_recursive(C, event, menu);
+
+ /* free if done, does not free handle itself */
+ if(menu->menuretval) {
+ ui_menu_block_free(C, menu);
+ WM_event_remove_ui_handler(&C->window->handlers, ui_handler_popup, ui_handler_remove_popup, menu);
+
+ if(menu->menuretval == UI_RETURN_OK && menu->popup_func)
+ menu->popup_func(C, menu->popup_arg, menu->retvalue);
+ }
+ else {
+ /* re-enable tooltips */
+ if(event->type == MOUSEMOVE && (event->x!=event->prevx || event->y!=event->prevy))
+ ui_blocks_set_tooltips(menu->region, 1);
+ }
+
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
+
+ /* we block all events, this is modal interaction */
+ return WM_UI_HANDLER_BREAK;
+}
+
+static void ui_handler_remove_popup(bContext *C, void *userdata)
+{
+ uiMenuBlockHandle *menu= userdata;
+
+ /* free menu block if window is closed for some reason */
+ ui_menu_block_free(C, menu);
+
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
+}
+
void UI_add_region_handlers(ListBase *handlers)
{
- WM_event_remove_ui_handler(handlers);
- WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region);
+ WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL);
+ WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL);
+}
+
+void UI_add_popup_handlers(ListBase *handlers, uiMenuBlockHandle *menu)
+{
+ WM_event_add_ui_handler(NULL, handlers, ui_handler_popup, ui_handler_remove_popup, menu);
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 2e01eb8c8b1..0c7613bbfcd 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1,4 +1,5 @@
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -585,10 +586,8 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
{
uiBlock *block;
- for(block=ar->uiblocks.first; block; block=block->next) {
- wm_subwindow_getmatrix(C->window, ar->swinid, block->winmat);
+ for(block=ar->uiblocks.first; block; block=block->next)
uiDrawBlock(block);
- }
}
uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockFuncFP block_func, void *arg)
@@ -666,6 +665,10 @@ uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *
/* adds subwindow */
ED_region_init(C, ar);
+
+ /* get winmat now that we actually have the subwindow */
+ wm_subwindow_set(C->window, ar->swinid);
+ wm_subwindow_getmatrix(C->window, ar->swinid, block->winmat);
/* notify change and redraw */
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
@@ -1604,9 +1607,10 @@ uiBlock *ui_block_func_PUPMENUCOL(bContext *C, uiMenuBlockHandle *handle, void *
return block;
}
-uiMenuBlockHandle *pupmenu_col(bContext *C, char *instr, int mx, int my, int maxrow)
+void pupmenu_col(bContext *C, char *instr, int mx, int my, int maxrow, uiPupmenuFunc func, void *arg)
{
uiPupMenuInfo info;
+ uiMenuBlockHandle *menu;
memset(&info, 0, sizeof(info));
info.instr= instr;
@@ -1614,181 +1618,61 @@ uiMenuBlockHandle *pupmenu_col(bContext *C, char *instr, int mx, int my, int max
info.my= my;
info.maxrow= maxrow;
- return ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENUCOL, &info);
+ menu= ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENUCOL, &info);
+ menu->popup= 1;
+
+ UI_add_popup_handlers(&C->window->handlers, menu);
+ WM_event_add_mousemove(C);
+
+ menu->popup_func= func;
+ menu->popup_arg= arg;
}
-uiMenuBlockHandle *pupmenu(bContext *C, char *instr, int mx, int my)
+void pupmenu(bContext *C, char *instr, int mx, int my, uiPupmenuFunc func, void *arg)
{
uiPupMenuInfo info;
+ uiMenuBlockHandle *menu;
memset(&info, 0, sizeof(info));
info.instr= instr;
info.mx= mx;
info.my= my;
- return ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENU, &info);
-}
+ menu= ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENU, &info);
+ menu->popup= 1;
+ UI_add_popup_handlers(&C->window->handlers, menu);
+ WM_event_add_mousemove(C);
-void pupmenu_free(bContext *C, uiMenuBlockHandle *handle)
-{
- ui_menu_block_free(C, handle);
+ menu->popup_func= func;
+ menu->popup_arg= arg;
}
-/*************** Temporary Buttons Tests **********************/
-
-static uiBlock *test_submenu(bContext *C, uiMenuBlockHandle *handle, void *arg)
+/* XXX test */
+static void operator_callback(bContext *C, void *arg, int retval)
{
- ARegion *ar= handle->region;
- uiBlock *block;
- short yco= 0, menuwidth=120;
-
- block= uiBeginBlock(C, ar, "test_viewmenu", UI_EMBOSSP, UI_HELV);
- //uiBlockSetButmFunc(block, do_test_viewmenu, NULL);
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Seconds|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT,
- "Only Selected Data Keys|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Marker|PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Marker|PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Key|Ctrl PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Key|Ctrl PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center View|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT,
- "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
-
- uiBlockSetDirection(block, UI_RIGHT);
+ const char *opname= arg;
- uiTextBoundsBlock(block, 50);
- uiEndBlock(C, block);
-
- return block;
+ if(retval > 0)
+ WM_operator_call(C, opname);
}
-static uiBlock *test_viewmenu(bContext *C, uiMenuBlockHandle *handle, void *arg_area)
+void okee_operator(bContext *C, char *opname, char *str, ...)
{
- ScrArea *area= arg_area;
- ARegion *ar= handle->region;
- uiBlock *block;
- short yco= 0, menuwidth=120;
-
- block= uiBeginBlock(C, ar, "test_viewmenu", UI_EMBOSSP, UI_HELV);
- //uiBlockSetButmFunc(block, do_test_viewmenu, NULL);
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Seconds|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT,
- "Only Selected Data Keys|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Marker|PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Marker|PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Key|Ctrl PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Key|Ctrl PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center View|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT,
- "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBlockBut(block, test_submenu, NULL, ICON_RIGHTARROW_THIN, "Sub Menu", 0, yco-=20, 120, 19, "");
- uiDefIconTextBlockBut(block, test_submenu, NULL, ICON_RIGHTARROW_THIN, "Sub Menu", 0, yco-=20, 120, 19, "");
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- if(area->headertype==HEADERTOP) {
- uiBlockSetDirection(block, UI_DOWN);
- }
- else {
- uiBlockSetDirection(block, UI_TOP);
- uiBlockFlipOrder(block);
- }
-
- uiTextBoundsBlock(block, 50);
- uiEndBlock(C, block);
-
- return block;
-}
-
-void uiTestRegion(const bContext *C)
-{
- uiBlock *block;
- short xco;
-
- static float testcol[3];
- static char testtext[64];
- static float testnumf=5.0f;
- static short testchoice= 0, testtog= 0, testicontog= 0;
-
-#if 0
- static CurveMapping *cumap= NULL;
- static ColorBand *coba= NULL;
-#endif
-
- block= uiBeginBlock(C, C->region, "header buttons", UI_EMBOSS, UI_HELV);
-
- uiDefPulldownBut(block, test_viewmenu, C->area, "View",
- 13, 1, 50, 24, "");
-
- uiDefBut(block, BUT, 31415, "Type BUT",
- 13+50+5, 3, 80, 20, NULL, 0, 0, 0, 0, "A tooltip.");
- uiDefButS(block, MENU, 31416, "Gather Method%t|Raytrace %x0|Approximate %x1",
- 13+50+5+80+5, 3, 100, 20, &testchoice, 0, 0, 0, 0, "Method for occlusion gathering");
- uiDefButBitS(block, TOG, 1, 31417, "Pixel Cache",
- 13+50+5+80+5+100+5, 3, 100, 20, &testtog, 0, 0, 0, 0, "Cache AO results in pixels and interpolate over neighbouring pixels for speedup.");
-
- uiDefBut(block, TEX, 31418, "Text: ",
- 13+50+5+80+5+100+5+100+5, 3, 200, 20, testtext, 0, sizeof(testtext), 0, 0, "User defined text");
-
- uiDefButF(block, NUMSLI, 31419, "Slider: ",
- 13+50+5+80+5+100+5+100+5+200+5, 3, 150, 20, &testnumf, 0.0, 10.0, 0, 0, "Some tooltip.");
- uiDefButF(block, NUM, 31419, "N: ",
- 13+50+5+80+5+100+5+100+5+200+5+150+5, 3, 100, 20, &testnumf, 0.0, 10.0, 0, 0, "Some tooltip.");
+ va_list ap;
+ char *s, buf[512];
+ int mx, my;
- uiDefButF(block, COL, 3142, "",
- 13+50+5+80+5+100+5+100+5+200+5+150+5+100+5, 3, 100, 20, testcol, 0, 0, 0, 0 /*B_BANDCOL*/, "");
+ mx= C->window->eventstate->x;
+ my= C->window->eventstate->y;
- xco = 13+50+5+80+5+100+5+100+5+200+5+150+5+100+5+100+5;
- uiDefIconButBitS(block, ICONTOG, 1 /*AUTOKEY_ON*/, REDRAWINFO, ICON_PYTHON,
- xco, 3, 20, 20, &testicontog, 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones");
- xco += 5;
+ va_start(ap, str);
-#if 0
- if(!cumap) {
- cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
- cumap->flag &= ~CUMA_DO_CLIP;
- }
- if(!coba)
- coba= add_colorband(0);
+ s= buf;
+ s += sprintf(s, "OK? %%i%d%%t|", ICON_HELP);
+ vsprintf(s, str, ap);
+ va_end(ap);
- uiDefBut(block, BUT_CURVE, 3143, "",
- 13+400, 33, 100, 100, cumap, 0.0f, 1.0f, 0, 0, "");
- uiDefBut(block, BUT_COLORBAND, 3143, "",
- 13+400+100+10, 33, 150, 30, coba, 0.0f, 1.0f, 0, 0, "");
-#endif
-
- uiEndBlock(C, block);
- uiDrawBlock(block);
+ pupmenu(C, buf, mx, my, operator_callback, opname);
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index b0fdcee2c04..a2544e3e6e5 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -79,8 +79,11 @@ struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBa
void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap);
struct wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers,
- int (*func)(bContext *C, struct wmEvent *event), void (*remove)(bContext *C));
-void WM_event_remove_ui_handler(ListBase *handlers);
+ int (*func)(bContext *C, struct wmEvent *event, void *userdata),
+ void (*remove)(bContext *C, void *userdata), void *userdata);
+void WM_event_remove_ui_handler(ListBase *handlers,
+ int (*func)(bContext *C, struct wmEvent *event, void *userdata),
+ void (*remove)(bContext *C, void *userdata), void *userdata);
struct wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op);
void WM_event_remove_handlers(bContext *C, ListBase *handlers);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index b301976aeae..7307cb4bf23 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -91,8 +91,8 @@ typedef struct wmEvent {
#define WM_UI_HANDLER_CONTINUE 0
#define WM_UI_HANDLER_BREAK 1
-typedef int (*wmUIHandlerFunc)(bContext *C, struct wmEvent *event);
-typedef void (*wmUIHandlerRemoveFunc)(bContext *C);
+typedef int (*wmUIHandlerFunc)(bContext *C, struct wmEvent *event, void *userdata);
+typedef void (*wmUIHandlerRemoveFunc)(bContext *C, void *userdata);
/* ************** Notifiers ****************** */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index aeb3899409f..a5cbc835168 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -393,7 +393,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
if(handler->ui_area) C->area= handler->ui_area;
if(handler->ui_region) C->region= handler->ui_region;
- handler->ui_remove(C);
+ handler->ui_remove(C, handler->ui_userdata);
C->area= area;
C->region= region;
@@ -494,7 +494,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
if(handler->ui_area) C->area= handler->ui_area;
if(handler->ui_region) C->region= handler->ui_region;
- retval= handler->ui_handle(C, event);
+ retval= handler->ui_handle(C, event, handler->ui_userdata);
/* putting back screen context */
C->area= area;
@@ -748,11 +748,12 @@ void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap)
}
}
-wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove)
+wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata)
{
wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event ui handler");
handler->ui_handle= func;
handler->ui_remove= remove;
+ handler->ui_userdata= userdata;
handler->ui_area= (C)? C->area: NULL;
handler->ui_region= (C)? C->region: NULL;
@@ -761,12 +762,12 @@ wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHan
return handler;
}
-void WM_event_remove_ui_handler(ListBase *handlers)
+void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata)
{
wmEventHandler *handler;
for(handler= handlers->first; handler; handler= handler->next) {
- if(handler->ui_handle) {
+ if(handler->ui_handle == func && handler->ui_remove == remove && handler->ui_userdata == userdata) {
BLI_remlink(handlers, handler);
wm_event_free_handler(handler);
MEM_freeN(handler);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 5dd36d737b1..5ed29a28abd 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -46,6 +46,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "UI_interface.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -141,6 +143,22 @@ static void WM_OT_exit_blender(wmOperatorType *ot)
ot->poll= WM_operator_winactive;
}
+static int exit_okee_blender_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ okee_operator(C, "WM_OT_exit_blender", "Quit Blender");
+
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_exit_okee_blender(wmOperatorType *ot)
+{
+ ot->name= "Exit Blender";
+ ot->idname= "WM_OT_exit_okee_blender";
+
+ ot->invoke= exit_okee_blender_invoke;
+ ot->poll= WM_operator_winactive;
+}
+
/* ************ window gesture operator-callback definitions ************** */
/*
* These are default callbacks for use in operators requiring gesture input
@@ -346,6 +364,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_save_homefile);
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
WM_operatortype_append(WM_OT_exit_blender);
+ WM_operatortype_append(WM_OT_exit_okee_blender);
WM_operatortype_append(WM_OT_tweak_gesture);
}
@@ -358,6 +377,6 @@ void wm_window_keymap(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_verify_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_verify_item(keymap, "WM_OT_exit_okee_blender", QKEY, KM_PRESS, KM_CTRL, 0);
}
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index d4dddf8e222..26c0b23df30 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -55,6 +55,7 @@ typedef struct wmEventHandler {
/* ui handler */
wmUIHandlerFunc ui_handle; /* callback receiving events */
wmUIHandlerRemoveFunc ui_remove; /* callback when handler is removed */
+ void *ui_userdata; /* user data pointer */
struct ScrArea *ui_area; /* for derived/modal handlers */
struct ARegion *ui_region; /* for derived/modal handlers */