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.h97
-rw-r--r--source/blender/editors/interface/interface.c46
-rw-r--r--source/blender/editors/interface/interface.h28
-rw-r--r--source/blender/editors/interface/interface_handlers.c (renamed from source/blender/editors/interface/interface_ops.c)1609
-rw-r--r--source/blender/editors/interface/interface_regions.c70
-rw-r--r--source/blender/editors/screen/area.c4
-rw-r--r--source/blender/editors/screen/screen_edit.c10
-rw-r--r--source/blender/editors/screen/spacetypes.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c16
-rw-r--r--source/blender/editors/space_time/space_time.c4
-rw-r--r--source/blender/makesdna/DNA_screen_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_brush.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
-rw-r--r--source/blender/windowmanager/WM_api.h8
-rw-r--r--source/blender/windowmanager/WM_types.h9
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c119
-rw-r--r--source/blender/windowmanager/wm_event_system.h16
-rw-r--r--source/blender/windowmanager/wm_event_types.h2
18 files changed, 1065 insertions, 981 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 2a5c934ce42..dc48cf820f3 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -37,6 +37,8 @@ struct wmWindow;
struct wmWindowManager;
struct AutoComplete;
struct bContext;
+struct PointerRNA;
+struct PropertyRNA;
/* uiBlock->dt */
#define UI_EMBOSS 0 /* use one of the themes for drawing */
@@ -72,7 +74,7 @@ struct bContext;
#define UI_BLOCK_MOVEMOUSE_QUIT 128
#define UI_BLOCK_KEEP_OPEN 256
-/* uiMenuBlockHandle->blockretval */
+/* uiMenuBlockHandle->menuretval */
#define UI_RETURN_CANCEL 1 /* cancel all menus cascading */
#define UI_RETURN_OK 2 /* choice made */
#define UI_RETURN_OUT 4 /* left the menu */
@@ -167,50 +169,69 @@ struct bContext;
#define NUMABS (36<<9)
#define BUTTYPE (63<<9)
-/* Menu Block Handle */
+typedef struct uiBut uiBut;
+typedef struct uiBlock uiBlock;
+
+/* Common Drawing Functions */
+
+void uiEmboss(float x1, float y1, float x2, float y2, int sel);
+void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad, int active);
+void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad);
+void uiSetRoundBox(int type);
+void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad);
+void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag);
+void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
+
+/* Popup Menu's */
+
typedef struct uiMenuBlockHandle {
struct ARegion *region;
int butretval;
- int blockretval;
+ int menuretval;
float retvalue;
float retvec[3];
} uiMenuBlockHandle;
-typedef struct uiBut uiBut;
-typedef struct uiBlock uiBlock;
+typedef uiBlock* (*uiBlockFuncFP)(struct bContext *C, struct uiMenuBlockHandle *handle, void *arg1);
-void uiEmboss(float x1, float y1, float x2, float y2, int sel);
-void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad, int active);
-void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad);
-void uiSetRoundBox(int type);
-void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad);
+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);
-void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag);
-void uiTextBoundsBlock(uiBlock *block, int addval);
-void uiBoundsBlock(struct uiBlock *block, int addval);
-void uiDrawBlock(struct uiBlock *block);
-void uiGetMouse(int win, short *adr);
-void uiComposeLinks(uiBlock *block);
-void uiSetButLock(int val, char *lockstr);
-uiBut *uiFindInlink(uiBlock *block, void *poin);
-void uiClearButLock(void);
-int uiDoBlocks(struct ListBase *lb, int event, int movemouse_quit);
-void uiSetCurFont(uiBlock *block, int index);
-void uiDefFont(unsigned int index, void *xl, void *large, void *medium, void *small);
-void uiFreeBlock(uiBlock *block);
-void uiFreeBlocks(struct ListBase *lb);
-uiBlock *uiBeginBlock(struct wmWindow *window, struct ARegion *region, char *name, short dt, short font);
-void uiEndBlock(uiBlock *block);
+/* Block */
+
+uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, char *name, short dt, short font);
+void uiEndBlock(const struct bContext *C, uiBlock *block);
uiBlock *uiGetBlock(char *name, struct ARegion *ar);
+void uiFreeBlock(const struct bContext *C, uiBlock *block);
+void uiFreeBlocks(const struct bContext *C, struct ListBase *lb);
-void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
+void uiBoundsBlock(struct uiBlock *block, int addval);
+void uiDrawBlock(struct uiBlock *block);
+void uiTextBoundsBlock(uiBlock *block, int addval);
+void uiBlockSetButLock(uiBlock *block, int val, char *lockstr);
+void uiBlockClearButLock(uiBlock *block);
/* automatic aligning, horiz or verical */
void uiBlockBeginAlign(uiBlock *block);
void uiBlockEndAlign(uiBlock *block);
+/* Misc */
+
+void uiSetCurFont(uiBlock *block, int index);
+void *uiSetCurFont_ext(float aspect);
+void uiDefFont(unsigned int index, void *xl, void *large, void *medium, void *small);
+
+void uiComposeLinks(uiBlock *block);
+uiBut *uiFindInlink(uiBlock *block, void *poin);
+
+void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
+
+/* Defining Buttons */
+
uiBut *uiDefBut(uiBlock *block,
int type, int retval, char *str,
short x1, short y1,
@@ -258,7 +279,6 @@ typedef void (*uiIDPoinFuncFP) (char *str, struct ID **idpp);
uiBut *uiDefIDPoinBut(struct uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
short x1, short y1, short x2, short y2, void *idpp, char *tip);
-typedef uiBlock* (*uiBlockFuncFP) (struct wmWindow *window, struct uiMenuBlockHandle *handle, void *arg1);
uiBut *uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *func_arg1, char *str, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefPulldownBut(uiBlock *block, uiBlockFuncFP func, void *func_arg1, char *str, short x1, short y1, short x2, short y2, char *tip);
@@ -267,8 +287,6 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, int retv
void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip);
-struct PointerRNA;
-struct PropertyRNA;
uiBut *uiDefRNABut(uiBlock *block, int retval, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, short x1, short y1, short x2, short y2);
void uiButSetFunc3(uiBut *but, void (*func)(void *arg1, void *arg2, void *arg3), void *arg1, void *arg2, void *arg3);
@@ -306,11 +324,7 @@ void uiButSetCompleteFunc(uiBut *but, void (*func)(char *str, void *arg), void
void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(struct ScrArea *sa, uiBlock *block));
-
-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);
+/* Panels */
extern void uiFreePanels(struct ListBase *lb);
extern void uiNewPanelTabbed(char *, char *);
@@ -329,8 +343,7 @@ extern int uiAlignPanelStep(struct ScrArea *sa, float fac);
extern void uiPanelControl(int);
extern void uiSetPanelHandler(int);
-extern void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
-extern void *uiSetCurFont_ext(float aspect);
+/* Autocomplete */
typedef struct AutoComplete AutoComplete;
@@ -338,13 +351,17 @@ AutoComplete *autocomplete_begin(char *startname, int maxlen);
void autocomplete_do_name(AutoComplete *autocpl, const char *name);
void autocomplete_end(AutoComplete *autocpl, char *autoname);
-void uiTestRegion(const struct bContext *C); /* XXX 2.50 temporary test */
+/* Handlers for regions with UI blocks */
+
+void UI_add_region_handlers(struct ListBase *handlers);
+
+/* Module initialization and exit */
-void UI_keymap(struct wmWindowManager *wm);
-void UI_operatortypes(void);
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.c b/source/blender/editors/interface/interface.c
index 84525fc3046..c308ae63e3e 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -78,7 +78,7 @@
* ui_blah_blah() internal function
*/
-static void ui_free_but(uiBut *but);
+static void ui_free_but(const bContext *C, uiBut *but);
/* ************ GLOBALS ************* */
@@ -109,8 +109,8 @@ void ui_block_to_window_fl(const ARegion *ar, uiBlock *block, float *x, float *y
float gx, gy;
int sx, sy, getsizex, getsizey;
- getsizex= ar->winrct.xmax-ar->winrct.xmin;
- getsizey= ar->winrct.ymax-ar->winrct.ymin;
+ getsizex= ar->winrct.xmax-ar->winrct.xmin+1;
+ getsizey= ar->winrct.ymax-ar->winrct.ymin+1;
sx= ar->winrct.xmin;
sy= ar->winrct.ymin;
@@ -152,8 +152,8 @@ void ui_window_to_block_fl(const ARegion *ar, uiBlock *block, float *x, float *y
float a, b, c, d, e, f, px, py;
int sx, sy, getsizex, getsizey;
- getsizex= ar->winrct.xmax-ar->winrct.xmin;
- getsizey= ar->winrct.ymax-ar->winrct.ymin;
+ getsizex= ar->winrct.xmax-ar->winrct.xmin+1;
+ getsizey= ar->winrct.ymax-ar->winrct.ymin+1;
sx= ar->winrct.xmin;
sy= ar->winrct.ymin;
@@ -426,7 +426,7 @@ static int ui_but_equals_old(uiBut *but, uiBut *oldbut)
return 1;
}
-static int ui_but_update_from_old_block(uiBlock *block, uiBut *but)
+static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut *but)
{
uiBlock *oldblock;
uiBut *oldbut;
@@ -438,9 +438,9 @@ static int ui_but_update_from_old_block(uiBlock *block, uiBut *but)
for(oldbut=oldblock->buttons.first; oldbut; oldbut=oldbut->next) {
if(ui_but_equals_old(oldbut, but)) {
- if(oldbut->activate) {
+ if(oldbut->active) {
but->flag= oldbut->flag;
- but->activate= oldbut->activate;
+ but->active= oldbut->active;
but->pos= oldbut->pos;
but->editstr= oldbut->editstr;
but->editval= oldbut->editval;
@@ -450,12 +450,14 @@ static int ui_but_update_from_old_block(uiBlock *block, uiBut *but)
but->selsta= oldbut->selsta;
but->selend= oldbut->selend;
found= 1;
+
+ oldbut->active= NULL;
}
/* ensures one button can get activated, and in case the buttons
* draw are the same this gives O(1) lookup for each button */
BLI_remlink(&oldblock->buttons, oldbut);
- ui_free_but(oldbut);
+ ui_free_but(C, oldbut);
break;
}
@@ -464,7 +466,7 @@ static int ui_but_update_from_old_block(uiBlock *block, uiBut *but)
return found;
}
-void uiEndBlock(uiBlock *block)
+void uiEndBlock(const bContext *C, uiBlock *block)
{
uiBut *but;
@@ -473,14 +475,15 @@ void uiEndBlock(uiBlock *block)
* blocking, while still alowing buttons to be remade each redraw as it
* is expected by blender code */
for(but=block->buttons.first; but; but=but->next)
- if(ui_but_update_from_old_block(block, but))
+ if(ui_but_update_from_old_block(C, block, but))
ui_check_but(but);
if(block->oldblock) {
block->auto_open= block->oldblock->auto_open;
block->auto_open_last= block->oldblock->auto_open_last;
+ block->tooltipdisabled= block->oldblock->tooltipdisabled;
- uiFreeBlock(block->oldblock);
+ uiFreeBlock(C, block->oldblock);
block->oldblock= NULL;
}
@@ -1340,21 +1343,22 @@ static void ui_free_link(uiLink *link)
}
}
-static void ui_free_but(uiBut *but)
+static void ui_free_but(const bContext *C, uiBut *but)
{
+ if(but->active) ui_button_active_cancel(C, but);
if(but->str && but->str != but->strdata) MEM_freeN(but->str);
ui_free_link(but->link);
MEM_freeN(but);
}
-void uiFreeBlock(uiBlock *block)
+void uiFreeBlock(const bContext *C, uiBlock *block)
{
uiBut *but;
while( (but= block->buttons.first) ) {
BLI_remlink(&block->buttons, but);
- ui_free_but(but);
+ ui_free_but(C, but);
}
if(block->panel) block->panel->active= 0;
@@ -1364,22 +1368,24 @@ void uiFreeBlock(uiBlock *block)
MEM_freeN(block);
}
-void uiFreeBlocks(ListBase *lb)
+void uiFreeBlocks(const bContext *C, ListBase *lb)
{
uiBlock *block;
while( (block= lb->first) ) {
BLI_remlink(lb, block);
- uiFreeBlock(block);
+ uiFreeBlock(C, block);
}
}
-uiBlock *uiBeginBlock(wmWindow *window, ARegion *region, char *name, short dt, short font)
+uiBlock *uiBeginBlock(const bContext *C, ARegion *region, char *name, short dt, short font)
{
ListBase *lb;
uiBlock *block, *oldblock= NULL;
+ wmWindow *window;
int getsizex, getsizey;
+ window= C->window;
lb= &region->uiblocks;
/* each listbase only has one block with this name, free block
@@ -2071,7 +2077,7 @@ void autocomplete_end(AutoComplete *autocpl, char *autoname)
/* autocomplete callback for ID buttons */
static void autocomplete_id(char *str, void *arg_v)
{
- /* XXX 2.48 int blocktype= (intptr_t)arg_v; */
+ /* int blocktype= (intptr_t)arg_v; */
ListBase *listb= NULL /* XXX 2.50 needs context, wich_libbase(G.main, blocktype) */;
if(listb==NULL) return;
@@ -2510,7 +2516,7 @@ uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int
ui_check_but(but);
if(blocktype)
- uiButSetCompleteFunc(but, autocomplete_id, 0 /* XXX 2.48 (void *)(intptr_t)blocktype*/);
+ uiButSetCompleteFunc(but, autocomplete_id, (void *)(intptr_t)blocktype);
return but;
}
diff --git a/source/blender/editors/interface/interface.h b/source/blender/editors/interface/interface.h
index 4233e635b56..f6fb929f7b1 100644
--- a/source/blender/editors/interface/interface.h
+++ b/source/blender/editors/interface/interface.h
@@ -33,9 +33,10 @@
#include "UI_resources.h"
#include "RNA_types.h"
-struct uiActivateBut;
+struct uiHandleButtonData;
struct wmWindow;
struct ARegion;
+struct bContext;
/* general defines */
@@ -54,12 +55,6 @@ struct ARegion;
#define UI_HAS_ICON 8
/* warn: rest of uiBut->flag in BIF_interface.c */
-/* uiBut->activateflag */
-#define UI_ACTIVATE 1
-#define UI_ACTIVATE_APPLY 2
-#define UI_ACTIVATE_TEXT_EDITING 4
-#define UI_ACTIVATE_OPEN 8
-
/* internal panel drawing defines */
#define PNL_GRID 4
#define PNL_DIST 8
@@ -170,9 +165,8 @@ struct uiBut {
struct PropertyRNA *rnaprop;
int rnaindex;
- /* Activation data */
- struct uiActivateBut *activate;
- int activateflag;
+ /* activation button data */
+ struct uiHandleButtonData *active;
char *editstr;
double *editval;
@@ -222,9 +216,12 @@ struct uiBlock {
char *lockstr;
float xofs, yofs; // offset to parent button
+
rctf safety; // pulldowns, to detect outside, can differ per case how it is created
ListBase saferct; // uiSafetyRct list
+
uiMenuBlockHandle *handle; // handle
+ int tooltipdisabled; // to avoid tooltip after click
};
typedef struct uiSafetyRct {
@@ -260,10 +257,10 @@ extern int ui_is_but_float(uiBut *but);
extern void ui_update_block_buts_hsv(uiBlock *block, float *hsv);
/* interface_regions.c */
-uiBlock *ui_block_func_MENU(struct wmWindow *window, uiMenuBlockHandle *handle, void *arg_but);
-uiBlock *ui_block_func_ICONROW(struct wmWindow *window, uiMenuBlockHandle *handle, void *arg_but);
-uiBlock *ui_block_func_ICONTEXTROW(struct wmWindow *window, uiMenuBlockHandle *handle, void *arg_but);
-uiBlock *ui_block_func_COL(struct wmWindow *window, uiMenuBlockHandle *handle, void *arg_but);
+uiBlock *ui_block_func_MENU(struct bContext *C, uiMenuBlockHandle *handle, void *arg_but);
+uiBlock *ui_block_func_ICONROW(struct bContext *C, uiMenuBlockHandle *handle, void *arg_but);
+uiBlock *ui_block_func_ICONTEXTROW(struct bContext *C, uiMenuBlockHandle *handle, void *arg_but);
+uiBlock *ui_block_func_COL(struct bContext *C, uiMenuBlockHandle *handle, void *arg_but);
struct ARegion *ui_tooltip_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
void ui_tooltip_free(struct bContext *C, struct ARegion *ar);
@@ -289,5 +286,8 @@ extern void ui_draw_tria_icon(float x, float y, float aspect, char dir);
extern void ui_draw_anti_x(float x1, float y1, float x2, float y2);
extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select);
+/* interface_handlers.c */
+extern void ui_button_active_cancel(const struct bContext *C, uiBut *but);
+
#endif
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_handlers.c
index f214fa89cd8..2c30b97f4ab 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -61,7 +61,15 @@
#define BUTTON_AUTO_OPEN_THRESH 0.3
#define BUTTON_MOUSE_TOWARDS_THRESH 1.0
-typedef enum uiActivateButState {
+typedef enum uiButtonActivateType {
+ BUTTON_ACTIVATE_OVER,
+ BUTTON_ACTIVATE,
+ BUTTON_ACTIVATE_APPLY,
+ BUTTON_ACTIVATE_TEXT_EDITING,
+ BUTTON_ACTIVATE_OPEN
+} uiButtonActivateType;
+
+typedef enum uiHandleButtonState {
BUTTON_STATE_INIT,
BUTTON_STATE_HIGHLIGHT,
BUTTON_STATE_WAIT_FLASH,
@@ -70,18 +78,26 @@ typedef enum uiActivateButState {
BUTTON_STATE_NUM_EDITING,
BUTTON_STATE_TEXT_EDITING,
BUTTON_STATE_TEXT_SELECTING,
- BUTTON_STATE_BLOCK_OPEN,
+ BUTTON_STATE_MENU_OPEN,
BUTTON_STATE_EXIT
-} uiActivateButState;
+} uiHandleButtonState;
-typedef struct uiActivateBut {
+typedef struct uiHandleMenuData {
+ uiMenuBlockHandle *handle;
+
+ int towardsx, towardsy;
+ double towardstime;
+ int dotowards;
+} uiHandleMenuData;
+
+typedef struct uiHandleButtonData {
+ wmWindow *window;
ARegion *region;
- wmOperator *operator;
int interactive;
/* overall state */
- uiActivateButState state;
+ uiHandleButtonState state;
int cancel, retval;
int applied, appliedinteractive;
wmTimerHandle *flashtimer;
@@ -98,7 +114,6 @@ typedef struct uiActivateBut {
ARegion *tooltip;
wmTimerHandle *tooltiptimer;
wmTimerHandle *autoopentimer;
- int tooltipdisabled;
/* text selection/editing */
int maxlen, selextend, selstartx;
@@ -110,12 +125,17 @@ typedef struct uiActivateBut {
float dragf, dragfstart;
CBData *dragcbd;
- /* block open */
- uiMenuBlockHandle *blockhandle;
- int blockretval;
-} uiActivateBut;
+ /* menu open */
+ uiHandleMenuData *menu;
+ int menuretval;
-static void button_activate_state(bContext *C, uiBut *but, uiActivateButState state);
+ /* post activate */
+ uiButtonActivateType posttype;
+ uiBut *postbut;
+} uiHandleButtonData;
+
+static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
+static int ui_handler_window(bContext *C, wmEvent *event);
/* ********************** button apply/revert ************************ */
@@ -127,7 +147,7 @@ static void ui_apply_but_func(uiBut *but)
but->func3(but->func_arg1, but->func_arg2, but->func_arg3);
}
-static void ui_apply_but_BUT(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_BUT(uiBut *but, uiHandleButtonData *data)
{
ui_apply_but_func(but);
@@ -135,7 +155,7 @@ static void ui_apply_but_BUT(uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_BUTM(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_BUTM(uiBut *but, uiHandleButtonData *data)
{
ui_set_but_val(but, but->min);
ui_apply_but_func(but);
@@ -144,7 +164,7 @@ static void ui_apply_but_BUTM(uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_BLOCK(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_BLOCK(uiBut *but, uiHandleButtonData *data)
{
if(but->type == COL)
ui_set_but_vectorf(but, data->vec);
@@ -157,7 +177,7 @@ static void ui_apply_but_BLOCK(uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_TOG(uiBlock *block, uiBut *but, uiActivateBut *data)
+static void ui_apply_but_TOG(uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
double value;
int w, lvalue, push;
@@ -216,7 +236,7 @@ static void ui_apply_but_TOG(uiBlock *block, uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_ROW(uiBlock *block, uiBut *but, uiActivateBut *data)
+static void ui_apply_but_ROW(uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
ui_set_but_val(but, but->max);
ui_apply_but_func(but);
@@ -225,7 +245,7 @@ static void ui_apply_but_ROW(uiBlock *block, uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_TEX(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_TEX(uiBut *but, uiHandleButtonData *data)
{
if(!data->str)
return;
@@ -243,7 +263,7 @@ static void ui_apply_but_TEX(uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_NUM(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_NUM(uiBut *but, uiHandleButtonData *data)
{
if(data->str) {
/* XXX 2.50 missing python api */
@@ -275,14 +295,14 @@ static void ui_apply_but_NUM(uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_LABEL(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_LABEL(uiBut *but, uiHandleButtonData *data)
{
ui_apply_but_func(but);
data->retval= but->retval;
data->applied= 1;
}
-static void ui_apply_but_TOG3(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_TOG3(uiBut *but, uiHandleButtonData *data)
{
if(but->pointype==SHO ) {
short *sp= (short *)but->poin;
@@ -315,7 +335,7 @@ static void ui_apply_but_TOG3(uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_VEC(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_VEC(uiBut *but, uiHandleButtonData *data)
{
ui_set_but_vectorf(but, data->vec);
ui_check_but(but);
@@ -325,21 +345,21 @@ static void ui_apply_but_VEC(uiBut *but, uiActivateBut *data)
data->applied= 1;
}
-static void ui_apply_but_COLORBAND(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_COLORBAND(uiBut *but, uiHandleButtonData *data)
{
ui_apply_but_func(but);
data->retval= but->retval;
data->applied= 1;
}
-static void ui_apply_but_CURVE(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_CURVE(uiBut *but, uiHandleButtonData *data)
{
ui_apply_but_func(but);
data->retval= but->retval;
data->applied= 1;
}
-static void ui_apply_but_IDPOIN(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_IDPOIN(uiBut *but, uiHandleButtonData *data)
{
but->idpoin_func(data->str, but->idpoin_idpp);
ui_check_but(but);
@@ -349,7 +369,7 @@ static void ui_apply_but_IDPOIN(uiBut *but, uiActivateBut *data)
}
#ifdef INTERNATIONAL
-static void ui_apply_but_CHARTAB(uiBut *but, uiActivateBut *data)
+static void ui_apply_but_CHARTAB(uiBut *but, uiHandleButtonData *data)
{
ui_apply_but_func(but);
data->retval= but->retval;
@@ -357,7 +377,7 @@ static void ui_apply_but_CHARTAB(uiBut *but, uiActivateBut *data)
}
#endif
-static void ui_apply_button(uiBlock *block, uiBut *but, uiActivateBut *data, int interactive)
+static void ui_apply_button(uiBlock *block, uiBut *but, uiHandleButtonData *data, int interactive)
{
char *editstr;
double *editval;
@@ -484,7 +504,7 @@ static void ui_apply_button(uiBlock *block, uiBut *but, uiActivateBut *data, int
/* ******************* copy and paste ******************** */
/* c = copy, v = paste */
-static void ui_but_copy_paste(bContext *C, uiBut *but, uiActivateBut *data, char mode)
+static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, char mode)
{
static ColorBand but_copypaste_coba = {0};
char buf[UI_MAX_DRAW_STR+1]= {0};
@@ -546,7 +566,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiActivateBut *data, char
/* text/string and ID data */
else if(ELEM(but->type, TEX, IDPOIN)) {
- uiActivateBut *data= but->activate;
+ uiHandleButtonData *data= but->active;
if(but->poin==NULL && but->rnapoin.data==NULL);
else if(mode=='c') {
@@ -629,7 +649,7 @@ static short test_special_char(char ch)
return 0;
}
-static int ui_textedit_delete_selection(uiBut *but, uiActivateBut *data)
+static int ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
{
char *str;
int x, changed;
@@ -651,7 +671,7 @@ static int ui_textedit_delete_selection(uiBut *but, uiActivateBut *data)
return changed;
}
-static void ui_textedit_set_cursor_pos(uiBut *but, uiActivateBut *data, short x)
+static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, short x)
{
char *origstr;
@@ -673,7 +693,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiActivateBut *data, short x)
MEM_freeN(origstr);
}
-static void ui_textedit_set_cursor_select(uiBut *but, uiActivateBut *data, short x)
+static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, short x)
{
if (x > data->selstartx) data->selextend = EXTEND_RIGHT;
else if (x < data->selstartx) data->selextend = EXTEND_LEFT;
@@ -686,7 +706,7 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiActivateBut *data, short
ui_check_but(but);
}
-static int ui_textedit_type_ascii(uiBut *but, uiActivateBut *data, char ascii)
+static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char ascii)
{
char *str;
int len, x, changed= 0;
@@ -711,10 +731,10 @@ static int ui_textedit_type_ascii(uiBut *but, uiActivateBut *data, char ascii)
}
}
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
-void ui_textedit_move(uiBut *but, uiActivateBut *data, int direction, int select, int jump)
+void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, int jump)
{
char *str;
int len;
@@ -817,7 +837,7 @@ void ui_textedit_move(uiBut *but, uiActivateBut *data, int direction, int select
}
}
-void ui_textedit_move_end(uiBut *but, uiActivateBut *data, int direction, int select)
+void ui_textedit_move_end(uiBut *but, uiHandleButtonData *data, int direction, int select)
{
char *str;
@@ -843,7 +863,7 @@ void ui_textedit_move_end(uiBut *but, uiActivateBut *data, int direction, int se
}
}
-static int ui_textedit_delete(uiBut *but, uiActivateBut *data, int direction, int all)
+static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, int all)
{
char *str;
int len, x, changed= 0;
@@ -886,7 +906,7 @@ static int ui_textedit_delete(uiBut *but, uiActivateBut *data, int direction, in
return changed;
}
-static int ui_textedit_autocomplete(uiBut *but, uiActivateBut *data)
+static int ui_textedit_autocomplete(uiBut *but, uiHandleButtonData *data)
{
char *str;
int changed= 1;
@@ -898,7 +918,7 @@ static int ui_textedit_autocomplete(uiBut *but, uiActivateBut *data)
return changed;
}
-static int ui_textedit_copypaste(uiBut *but, uiActivateBut *data, int paste, int copy, int cut)
+static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste, int copy, int cut)
{
char buf[UI_MAX_DRAW_STR]={0};
char *str, *p;
@@ -959,7 +979,7 @@ static int ui_textedit_copypaste(uiBut *but, uiActivateBut *data, int paste, int
return changed;
}
-static void ui_textedit_begin(uiBut *but, uiActivateBut *data)
+static void ui_textedit_begin(uiBut *but, uiHandleButtonData *data)
{
if(data->str) {
MEM_freeN(data->str);
@@ -1017,7 +1037,7 @@ static void ui_textedit_begin(uiBut *but, uiActivateBut *data)
ui_check_but(but);
}
-static void ui_textedit_end(uiBut *but, uiActivateBut *data)
+static void ui_textedit_end(uiBut *but, uiHandleButtonData *data)
{
if(but) {
but->editstr= 0;
@@ -1025,7 +1045,7 @@ static void ui_textedit_end(uiBut *but, uiActivateBut *data)
}
}
-static void ui_textedit_next_but(uiBlock *block, uiBut *actbut)
+static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data)
{
uiBut *but;
@@ -1035,19 +1055,21 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut)
for(but= actbut->next; but; but= but->next) {
if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
- but->activateflag= UI_ACTIVATE_TEXT_EDITING;
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
return;
}
}
for(but= block->buttons.first; but!=actbut; but= but->next) {
if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
- but->activateflag= UI_ACTIVATE_TEXT_EDITING;
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
return;
}
}
}
-static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut)
+static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data)
{
uiBut *but;
@@ -1057,28 +1079,30 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut)
for(but= actbut->prev; but; but= but->prev) {
if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
- but->activateflag= UI_ACTIVATE_TEXT_EDITING;
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
return;
}
}
for(but= block->buttons.last; but!=actbut; but= but->prev) {
if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
- but->activateflag= UI_ACTIVATE_TEXT_EDITING;
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
return;
}
}
}
-static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
- int mx, my, changed= 0, handled= 0;
+ int mx, my, changed= 0, retval= WM_UI_HANDLER_CONTINUE;
switch(event->type) {
case RIGHTMOUSE:
case ESCKEY:
data->cancel= 1;
button_activate_state(C, but, BUTTON_STATE_EXIT);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case LEFTMOUSE: {
if(event->val) {
@@ -1092,11 +1116,11 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiActiva
data->selstartx= mx;
button_activate_state(C, but, BUTTON_STATE_TEXT_SELECTING);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else {
button_activate_state(C, but, BUTTON_STATE_EXIT);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
}
break;
@@ -1116,64 +1140,64 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiActiva
else if(event->type == CKEY)
changed= ui_textedit_copypaste(but, data, 0, 0, 1);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
break;
case RIGHTARROWKEY:
ui_textedit_move(but, data, 1, event->shift, event->ctrl);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case LEFTARROWKEY:
ui_textedit_move(but, data, 0, event->shift, event->ctrl);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case DOWNARROWKEY:
case ENDKEY:
ui_textedit_move_end(but, data, 1, event->shift);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case UPARROWKEY:
case HOMEKEY:
ui_textedit_move_end(but, data, 0, event->shift);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case PADENTER:
case RETKEY:
button_activate_state(C, but, BUTTON_STATE_EXIT);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case DELKEY:
changed= ui_textedit_delete(but, data, 1, 0);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case BACKSPACEKEY:
changed= ui_textedit_delete(but, data, 0, event->shift);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
case TABKEY:
/* there is a key conflict here, we can't tab with autocomplete */
if(but->autocomplete_func) {
changed= ui_textedit_autocomplete(but, data);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
/* the hotkey here is not well defined, was G.qual so we check all */
else if(event->shift || event->ctrl || event->alt || event->oskey) {
- ui_textedit_prev_but(block, but);
+ ui_textedit_prev_but(block, but, data);
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else {
- ui_textedit_next_but(block, but);
+ ui_textedit_next_but(block, but, data);
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
}
- if(event->ascii && !handled) {
+ if(event->ascii && (retval == WM_UI_HANDLER_CONTINUE)) {
changed= ui_textedit_type_ascii(but, data, event->ascii);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
}
@@ -1182,13 +1206,13 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiActiva
else ui_check_but(but);
}
- if(changed || handled)
+ if(changed || (retval == WM_UI_HANDLER_BREAK))
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
}
-static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
- int mx, my, handled= 0;
+ int mx, my, retval= WM_UI_HANDLER_CONTINUE;
switch(event->type) {
case MOUSEMOVE: {
@@ -1197,17 +1221,17 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
ui_window_to_block(data->region, block, &mx, &my);
ui_textedit_set_cursor_select(but, data, mx);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
}
case LEFTMOUSE:
if(event->val == 0)
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
break;
}
- if(handled) {
+ if(retval == WM_UI_HANDLER_BREAK) {
ui_check_but(but);
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
}
@@ -1215,7 +1239,7 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
/* ************* number editing for various types ************* */
-static void ui_numedit_begin(uiBut *but, uiActivateBut *data)
+static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
{
float butrange;
@@ -1246,7 +1270,7 @@ static void ui_numedit_begin(uiBut *but, uiActivateBut *data)
data->draglock= 1;
}
-static void ui_numedit_end(uiBut *but, uiActivateBut *data)
+static void ui_numedit_end(uiBut *but, uiHandleButtonData *data)
{
but->editval= NULL;
but->editvec= NULL;
@@ -1260,7 +1284,7 @@ static void ui_numedit_end(uiBut *but, uiActivateBut *data)
data->dragsel= 0;
}
-static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data)
+static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
if(data->interactive) ui_apply_button(block, but, data, 1);
else ui_check_but(but);
@@ -1268,9 +1292,9 @@ static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiActivate
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
}
-/* ****************** block opening for various types **************** */
+/* ****************** menu opening for various types **************** */
-static void ui_blockopen_begin(bContext *C, uiBut *but, uiActivateBut *data)
+static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
{
uiBlockFuncFP func= NULL;
void *arg= NULL;
@@ -1307,14 +1331,16 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiActivateBut *data)
break;
}
- if(func)
- data->blockhandle= ui_menu_block_create(C, data->region, but, func, arg);
+ if(func) {
+ data->menu= MEM_callocN(sizeof(uiHandleMenuData), "uiHandleMenuData");
+ data->menu->handle= ui_menu_block_create(C, data->region, but, func, arg);
+ }
/* this makes adjacent blocks auto open from now on */
if(but->block->auto_open==0) but->block->auto_open= 1;
}
-static void ui_blockopen_end(bContext *C, uiBut *but, uiActivateBut *data)
+static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
{
if(but) {
but->editval= NULL;
@@ -1323,24 +1349,25 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiActivateBut *data)
but->block->auto_open_last= PIL_check_seconds_timer();
}
- if(data->blockhandle) {
- ui_menu_block_free(C, data->blockhandle);
- data->blockhandle= NULL;
+ if(data->menu) {
+ ui_menu_block_free(C, data->menu->handle);
+ MEM_freeN(data->menu);
+ data->menu= NULL;
}
}
/* ***************** events for different button types *************** */
-static int ui_do_but_BUT(bContext *C, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(event->type == LEFTMOUSE && event->val) {
button_activate_state(C, but, BUTTON_STATE_WAIT_RELEASE);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
else if(ELEM(event->type, PADENTER, RETKEY) && event->val) {
button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_WAIT_RELEASE) {
@@ -1348,23 +1375,24 @@ static int ui_do_but_BUT(bContext *C, uiBut *but, uiActivateBut *data, wmEvent *
if(!(but->flag & UI_SELECT))
data->cancel= 1;
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val) {
button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_WAIT_KEY_EVENT) {
if(event->type == MOUSEMOVE)
- return 0;
+ return WM_UI_HANDLER_CONTINUE;
/* XXX 2.50 missing function */
#if 0
@@ -1378,53 +1406,56 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiActivateBut *data, wmEven
}
#endif
}
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val) {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_TEXT_EDITING) {
ui_do_but_textedit(C, block, but, data, event);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
else if(data->state == BUTTON_STATE_TEXT_SELECTING) {
ui_do_but_textedit_select(C, block, but, data, event);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_TOG(bContext *C, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val) {
data->togdual= event->ctrl;
data->togonly= !event->shift;
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
- return 0;
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_EXIT(bContext *C, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_numedit_but_NUM(uiBut *but, uiActivateBut *data, float fac, int snap, int mx)
+static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx)
{
float deler, tempf;
int lvalue, temp, changed= 0;
@@ -1514,10 +1545,10 @@ static int ui_numedit_but_NUM(uiBut *but, uiActivateBut *data, float fac, int sn
return changed;
}
-static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
int mx, my, click= 0;
- int handled= 0;
+ int retval= WM_UI_HANDLER_CONTINUE;
mx= event->x;
my= event->y;
@@ -1527,13 +1558,13 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiActivateBut
if(event->val) {
if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->shift) {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else if(event->type == LEFTMOUSE) {
data->dragstartx= mx;
data->draglastx= mx;
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else if(ELEM(event->type, PADENTER, RETKEY) && event->val)
click= 1;
@@ -1567,15 +1598,15 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiActivateBut
if(ui_numedit_but_NUM(but, data, fac, snap, mx))
ui_numedit_apply(C, block, but, data);
}
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else if(data->state == BUTTON_STATE_TEXT_EDITING) {
ui_do_but_textedit(C, block, but, data, event);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else if(data->state == BUTTON_STATE_TEXT_SELECTING) {
ui_do_but_textedit_select(C, block, but, data, event);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
if(click) {
@@ -1632,13 +1663,14 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiActivateBut
else
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
}
- handled= 1;
+
+ retval= WM_UI_HANDLER_BREAK;
}
- return handled;
+ return retval;
}
-static int ui_numedit_but_SLI(uiBut *but, uiActivateBut *data, int shift, int ctrl, int mx)
+static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, int ctrl, int mx)
{
float deler, f, tempf;
int temp, lvalue, changed= 0;
@@ -1698,10 +1730,10 @@ static int ui_numedit_but_SLI(uiBut *but, uiActivateBut *data, int shift, int ct
return changed;
}
-static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
int mx, my, click= 0;
- int handled= 0;
+ int retval= WM_UI_HANDLER_CONTINUE;
mx= event->x;
my= event->y;
@@ -1722,7 +1754,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiActivateBut
else
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
@@ -1736,15 +1768,15 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiActivateBut
if(ui_numedit_but_SLI(but, data, event->shift, event->ctrl, mx))
ui_numedit_apply(C, block, but, data);
}
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else if(data->state == BUTTON_STATE_TEXT_EDITING) {
ui_do_but_textedit(C, block, but, data, event);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else if(data->state == BUTTON_STATE_TEXT_SELECTING) {
ui_do_but_textedit_select(C, block, but, data, event);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
if(click) {
@@ -1784,49 +1816,25 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiActivateBut
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
- return handled;
+ return retval;
}
-static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val) {
- button_activate_state(C, but, BUTTON_STATE_BLOCK_OPEN);
- return 1;
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ return WM_UI_HANDLER_BREAK;
}
}
- else if(data->state == BUTTON_STATE_BLOCK_OPEN) {
- if(event->type == MESSAGE) {
- uiMenuBlockHandle *handle= event->customdata;
-
- if(handle == data->blockhandle) {
- data->blockretval= handle->blockretval;
-
- if(handle->blockretval == UI_RETURN_OK) {
- if(but->type == COL)
- VECCOPY(data->vec, handle->retvec)
- else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
- data->value= handle->retvalue;
- }
- if(handle->blockretval == UI_RETURN_OUT)
- /* we close the block and proceed as if nothing happened */
- button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
- else
- /* ok/cancel, we exit and will send message in _exit */
- button_activate_state(C, but, BUTTON_STATE_EXIT);
-
- return 1;
- }
- }
- }
- return 0;
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_numedit_but_NORMAL(uiBut *but, uiActivateBut *data, int mx, int my)
+static int ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
float dx, dy, rad, radsq, mrad, *fp;
int mdx, mdy, changed= 1;
@@ -1882,7 +1890,7 @@ static int ui_numedit_but_NORMAL(uiBut *but, uiActivateBut *data, int mx, int my
return changed;
}
-static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
int mx, my;
@@ -1902,7 +1910,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiActivateB
if(ui_numedit_but_NORMAL(but, data, mx, my))
ui_numedit_apply(C, block, but, data);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
@@ -1914,13 +1922,14 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiActivateB
}
else if(event->type==LEFTMOUSE && event->val==0)
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+
+ return WM_UI_HANDLER_BREAK;
}
- return 0;
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_numedit_but_HSVCUBE(uiBut *but, uiActivateBut *data, int mx, int my)
+static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
float x, y;
int changed= 1;
@@ -1957,7 +1966,7 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiActivateBut *data, int mx, int m
return changed;
}
-static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
int mx, my;
@@ -1977,7 +1986,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiActivate
if(ui_numedit_but_HSVCUBE(but, data, mx, my))
ui_numedit_apply(C, block, but, data);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
@@ -1990,9 +1999,10 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiActivate
else if(event->type==LEFTMOUSE && event->val==0)
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
static int verg_colorband(const void *a1, const void *a2)
@@ -2001,7 +2011,7 @@ static int verg_colorband(const void *a1, const void *a2)
if( x1->pos > x2->pos ) return 1;
else if( x1->pos < x2->pos) return -1;
- return 0;
+ return WM_UI_HANDLER_CONTINUE;
}
static void ui_colorband_update(ColorBand *coba)
@@ -2020,7 +2030,7 @@ static void ui_colorband_update(ColorBand *coba)
}
}
-static int ui_numedit_but_COLORBAND(uiBut *but, uiActivateBut *data, int mx)
+static int ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx)
{
float dx;
int changed= 0;
@@ -2041,7 +2051,7 @@ static int ui_numedit_but_COLORBAND(uiBut *but, uiActivateBut *data, int mx)
return changed;
}
-static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
ColorBand *coba;
CBData *cbd;
@@ -2097,7 +2107,8 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiActiva
data->dragcbd= coba->data + coba->cur;
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
}
- return 1;
+
+ return WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
@@ -2110,12 +2121,13 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiActiva
else if(event->type==LEFTMOUSE && event->val==0)
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
-static int ui_numedit_but_CURVE(uiBut *but, uiActivateBut *data, int snap, int mx, int my)
+static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap, int mx, int my)
{
CurveMapping *cumap= data->cumap;
CurveMap *cuma= cumap->cm+cumap->cur;
@@ -2187,7 +2199,7 @@ static int ui_numedit_but_CURVE(uiBut *but, uiActivateBut *data, int snap, int m
return changed;
}
-static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
int mx, my, a, changed= 0;
@@ -2282,7 +2294,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiActivateBu
data->draglasty= my;
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
@@ -2312,13 +2324,15 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiActivateBu
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
- return 1;
+
+ return WM_UI_HANDLER_BREAK;
}
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
#ifdef INTERNATIONAL
-static int ui_do_but_CHARTAB(bContext *C, uiBlock *block, uiBut *but, uiActivateBut *data, wmEvent *event)
+static int ui_do_but_CHARTAB(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
/* XXX 2.50 bad global and state access */
#if 0
@@ -2363,7 +2377,7 @@ static int ui_do_but_CHARTAB(bContext *C, uiBlock *block, uiBut *but, uiActivate
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
else if(ELEM(event->type, WHEELUPMOUSE, PAGEUPKEY)) {
for(but= block->buttons.first; but; but= but->next) {
@@ -2387,7 +2401,8 @@ static int ui_do_but_CHARTAB(bContext *C, uiBlock *block, uiBut *but, uiActivate
break;
}
}
- return 1;
+
+ return WM_UI_HANDLER_BREAK;
}
else if(ELEM(event->type, WHEELDOWNMOUSE, PAGEDOWNKEY)) {
for(but= block->buttons.first; but; but= but->next)
@@ -2414,27 +2429,29 @@ static int ui_do_but_CHARTAB(bContext *C, uiBlock *block, uiBut *but, uiActivate
break;
}
}
- return 1;
+
+ return WM_UI_HANDLER_BREAK;
}
}
#endif
- return 0;
+
+ return WM_UI_HANDLER_CONTINUE;
}
#endif
static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
{
- uiActivateBut *data;
- int handled;
+ uiHandleButtonData *data;
+ int retval;
- data= but->activate;
- handled= 0;
+ data= but->active;
+ retval= WM_UI_HANDLER_CONTINUE;
/* handle copy-paste */
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM(event->type, CKEY, VKEY) && event->val && (event->ctrl || event->oskey)) {
ui_but_copy_paste(C, but, data, (event->type == CKEY)? 'c': 'v');
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
@@ -2444,23 +2461,23 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
if(but->lockstr) {
WM_report(C, WM_LOG_WARNING, but->lockstr);
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
else if(but->pointype && but->poin==0) {
/* there's a pointer needed */
WM_reportf(C, WM_LOG_WARNING, "DoButton pointer error: %s", but->str);
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return 1;
+ return WM_UI_HANDLER_BREAK;
}
}
switch(but->type) {
case BUT:
- handled= ui_do_but_BUT(C, but, data, event);
+ retval= ui_do_but_BUT(C, but, data, event);
break;
case KEYEVT:
- handled= ui_do_but_KEYEVT(C, but, data, event);
+ retval= ui_do_but_KEYEVT(C, but, data, event);
break;
case TOG:
case TOGR:
@@ -2468,7 +2485,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
case ICONTOGN:
case TOGN:
case BUT_TOGDUAL:
- handled= ui_do_but_TOG(C, but, data, event);
+ retval= ui_do_but_TOG(C, but, data, event);
break;
#if 0
case SCROLL:
@@ -2479,72 +2496,72 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
#endif
case NUM:
case NUMABS:
- handled= ui_do_but_NUM(C, block, but, data, event);
+ retval= ui_do_but_NUM(C, block, but, data, event);
break;
case SLI:
case NUMSLI:
case HSVSLI:
- handled= ui_do_but_SLI(C, block, but, data, event);
+ retval= ui_do_but_SLI(C, block, but, data, event);
break;
case ROUNDBOX:
case LABEL:
case TOG3:
case ROW:
- handled= ui_do_but_EXIT(C, but, data, event);
+ retval= ui_do_but_EXIT(C, but, data, event);
break;
case TEX:
case IDPOIN:
- handled= ui_do_but_TEX(C, block, but, data, event);
+ retval= ui_do_but_TEX(C, block, but, data, event);
break;
case MENU:
- handled= ui_do_but_BLOCK(C, but, data, event);
+ retval= ui_do_but_BLOCK(C, but, data, event);
break;
case ICONROW:
- handled= ui_do_but_BLOCK(C, but, data, event);
+ retval= ui_do_but_BLOCK(C, but, data, event);
break;
case ICONTEXTROW:
- handled= ui_do_but_BLOCK(C, but, data, event);
+ retval= ui_do_but_BLOCK(C, but, data, event);
break;
case BLOCK:
case PULLDOWN:
- handled= ui_do_but_BLOCK(C, but, data, event);
+ retval= ui_do_but_BLOCK(C, but, data, event);
break;
case BUTM:
- handled= ui_do_but_BUT(C, but, data, event);
+ retval= ui_do_but_BUT(C, but, data, event);
break;
case COL:
if(but->a1 == -1) // signal to prevent calling up color picker
- handled= ui_do_but_EXIT(C, but, data, event);
+ retval= ui_do_but_EXIT(C, but, data, event);
else
- handled= ui_do_but_BLOCK(C, but, data, event);
+ retval= ui_do_but_BLOCK(C, but, data, event);
break;
case BUT_NORMAL:
- handled= ui_do_but_NORMAL(C, block, but, data, event);
+ retval= ui_do_but_NORMAL(C, block, but, data, event);
break;
case BUT_COLORBAND:
- handled= ui_do_but_COLORBAND(C, block, but, data, event);
+ retval= ui_do_but_COLORBAND(C, block, but, data, event);
break;
case BUT_CURVE:
- handled= ui_do_but_CURVE(C, block, but, data, event);
+ retval= ui_do_but_CURVE(C, block, but, data, event);
break;
case HSVCUBE:
- handled= ui_do_but_HSVCUBE(C, block, but, data, event);
+ retval= ui_do_but_HSVCUBE(C, block, but, data, event);
break;
#ifdef INTERNATIONAL
case CHARTAB:
- handled= ui_do_but_CHARTAB(C, block, but, data, event);
+ retval= ui_do_but_CHARTAB(C, block, but, data, event);
break;
#endif
/* XXX 2.50 links not implemented yet */
#if 0
case LINK:
case INLINK:
- handled= retval= ui_do_but_LINK(block, but);
+ retval= retval= ui_do_but_LINK(block, but);
break;
#endif
}
- return handled;
+ return retval;
}
/* ************************ button utilities *********************** */
@@ -2554,124 +2571,99 @@ static int ui_but_contains_pt(uiBut *but, int mx, int my)
return ((but->x1<mx && but->x2>=mx) && (but->y1<my && but->y2>=my));
}
-static uiBut *ui_but_find_activated(ARegion *ar, uiActivateBut *data, uiBlock **rblock)
+static uiBut *ui_but_find_activated(ARegion *ar)
{
uiBlock *block;
uiBut *but;
- for(block=ar->uiblocks.first; block; block=block->next) {
- for(but=block->buttons.first; but; but= but->next) {
- if((but->activate == data && data) || (but->activate && data == NULL)) {
- if(rblock) *rblock= block;
+ for(block=ar->uiblocks.first; block; block=block->next)
+ for(but=block->buttons.first; but; but= but->next)
+ if(but->active)
return but;
- }
- }
- }
- if(rblock) *rblock= NULL;
return NULL;
}
-static uiBut *ui_but_find_signal(ARegion *ar, uiActivateBut *data, uiBlock **rblock)
+static void ui_blocks_set_tooltips(ARegion *ar, int enable)
{
uiBlock *block;
- uiBut *but;
-
- for(block=ar->uiblocks.first; block; block=block->next) {
- for(but=block->buttons.first; but; but= but->next) {
- if(but->activateflag) {
- if(rblock) *rblock= block;
- return but;
- }
- }
- }
- if(rblock) *rblock= NULL;
- return NULL;
-}
-
-static int inside_region(ARegion *ar, int x, int y)
-{
- if(BLI_in_rcti(&ar->winrct, x, y)) {
- /* XXX still can be zero */
- if(ar->v2d.mask.xmin!=ar->v2d.mask.xmax) {
- int arx = x;
- int ary = y;
- ui_window_to_region(ar, &arx, &ary);
- return BLI_in_rcti(&ar->v2d.mask, arx, ary);
- }
- return 1;
- }
- return 0;
+ /* 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)
+ block->tooltipdisabled= !enable;
}
-static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y, uiBlock **rblock)
+static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
{
- uiBlock *block, *blockover= NULL;
+ uiBlock *block;
uiBut *but, *butover= NULL;
int mx, my;
- if(inside_region(ar, x, y)) {
- for(block=ar->uiblocks.first; block; block=block->next) {
- mx= x;
- my= y;
- ui_window_to_block(ar, block, &mx, &my);
+ /* check if the mouse is in the region, and in case of a view2d also check
+ * if it is inside the view2d itself, not over scrollbars for example */
+ if(!BLI_in_rcti(&ar->winrct, x, y))
+ return NULL;
- for(but=block->buttons.first; but; but= but->next) {
- /* give precedence to already activated buttons */
- if(ui_but_contains_pt(but, mx, my)) {
- if(!butover || (!butover->activate && but->activate)) {
- butover= but;
- blockover= block;
- }
- }
- }
+ if(ar->v2d.mask.xmin!=ar->v2d.mask.xmax) {
+ mx= x;
+ my= y;
+ ui_window_to_region(ar, &mx, &my);
+
+ if(!BLI_in_rcti(&ar->v2d.mask, mx, my))
+ return NULL;
+ }
+
+ for(block=ar->uiblocks.first; block; block=block->next) {
+ mx= x;
+ my= y;
+ ui_window_to_block(ar, block, &mx, &my);
+
+ for(but=block->buttons.first; but; but= but->next) {
+ /* give precedence to already activated buttons */
+ if(ui_but_contains_pt(but, mx, my))
+ if(!butover || (!butover->active && but->active))
+ butover= but;
}
}
- if(rblock)
- *rblock= blockover;
return butover;
}
-/*********************** button activate operator ***************************
- * this operator runs from the moment the mouse is position over a button and
- * handles all interaction with the button, from highlight to text editing,
- * dragging, having a block open to leaving the button to activate another. */
+/* ****************** button state handling **************************/
-static void button_disable_timers(bContext *C, uiActivateBut *data)
+static int button_modal_state(uiHandleButtonState state)
{
- if(data->tooltiptimer) {
- WM_event_remove_window_timer(C->window, data->tooltiptimer);
- data->tooltiptimer= NULL;
- }
- if(data->tooltip) {
- ui_tooltip_free(C, data->tooltip);
- data->tooltip= NULL;
- }
- data->tooltipdisabled= 1;
+ return ELEM6(state, BUTTON_STATE_WAIT_RELEASE, BUTTON_STATE_WAIT_KEY_EVENT,
+ BUTTON_STATE_NUM_EDITING, BUTTON_STATE_TEXT_EDITING,
+ BUTTON_STATE_TEXT_SELECTING, BUTTON_STATE_MENU_OPEN);
+}
- if(data->autoopentimer) {
- WM_event_remove_window_timer(C->window, data->autoopentimer);
- data->autoopentimer= NULL;
- }
+static void button_tooltip_timer_start(uiBut *but)
+{
+ uiHandleButtonData *data;
+
+ data= but->active;
+
+ /* XXX 2.50 U missing from context */
+ if(U.flag & USER_TOOLTIPS)
+ if(!data->tooltiptimer && !but->block->tooltipdisabled)
+ data->tooltiptimer= WM_event_add_window_timer(data->window, BUTTON_TOOLTIP_DELAY, ~0);
}
-static void button_activate_state(bContext *C, uiBut *but, uiActivateButState state)
+static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state)
{
- uiActivateBut *data;
+ uiHandleButtonData *data;
- data= but->activate;
+ data= but->active;
if(data->state == state)
return;
+ /* highlight has timers for tooltips and auto open */
if(state == BUTTON_STATE_HIGHLIGHT) {
but->flag &= ~UI_SELECT;
- /* XXX 2.50 U missing from context */
- if(U.flag & USER_TOOLTIPS)
- if(!data->tooltiptimer && !data->tooltipdisabled)
- data->tooltiptimer= WM_event_add_window_timer(C->window, BUTTON_TOOLTIP_DELAY, ~0);
+ button_tooltip_timer_start(but);
/* automatic open pulldown block timer */
if(but->type==BLOCK || but->type==MENU || but->type==PULLDOWN || but->type==ICONTEXTROW) {
@@ -2684,309 +2676,290 @@ static void button_activate_state(bContext *C, uiBut *but, uiActivateButState st
else time= -1;
if(time >= 0)
- data->autoopentimer= WM_event_add_window_timer(C->window, time*20, ~0);
+ data->autoopentimer= WM_event_add_window_timer(data->window, time*20, ~0);
}
}
}
else {
but->flag |= UI_SELECT;
- button_disable_timers(C, data);
+
+ if(data->tooltiptimer) {
+ WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ data->tooltiptimer= NULL;
+ }
+ if(data->tooltip) {
+ ui_tooltip_free(C, data->tooltip);
+ data->tooltip= NULL;
+ }
+
+ if(data->autoopentimer) {
+ WM_event_remove_window_timer(data->window, data->autoopentimer);
+ data->autoopentimer= NULL;
+ }
}
+ /* text editing */
if(state == BUTTON_STATE_TEXT_EDITING && data->state != BUTTON_STATE_TEXT_SELECTING)
ui_textedit_begin(but, data);
else if(data->state == BUTTON_STATE_TEXT_EDITING && state != BUTTON_STATE_TEXT_SELECTING)
ui_textedit_end(but, data);
+ /* number editing */
if(state == BUTTON_STATE_NUM_EDITING)
ui_numedit_begin(but, data);
else if(data->state == BUTTON_STATE_NUM_EDITING)
ui_numedit_end(but, data);
- if(state == BUTTON_STATE_BLOCK_OPEN) {
+ /* menu open */
+ if(state == BUTTON_STATE_MENU_OPEN)
ui_blockopen_begin(C, but, data);
- /* note we move the handler to the region when the block is open,
- * so we don't interfere with the events as long as it's open */
- /* XXX (to brecht) removing this makes thing work proper */
- //WM_event_remove_modal_handler(&C->window->handlers, data->operator);
- //WM_event_add_modal_handler(C, &data->region->handlers, data->operator);
- }
- else if(data->state == BUTTON_STATE_BLOCK_OPEN) {
+ else if(data->state == BUTTON_STATE_MENU_OPEN)
ui_blockopen_end(C, but, data);
- /* XXX (to brecht) removing this makes thing work proper */
- //WM_event_remove_modal_handler(&data->region->handlers, data->operator);
- //WM_event_add_modal_handler(C, &C->window->handlers, data->operator);
- }
-
+
+ /* add a short delay before exiting, to ensure there is some feedback */
if(state == BUTTON_STATE_WAIT_FLASH) {
- data->flashtimer= WM_event_add_window_timer(C->window, BUTTON_FLASH_DELAY, ~0);
+ data->flashtimer= WM_event_add_window_timer(data->window, BUTTON_FLASH_DELAY, ~0);
}
else if(data->flashtimer) {
- WM_event_remove_window_timer(C->window, data->flashtimer);
+ WM_event_remove_window_timer(data->window, data->flashtimer);
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);
+ }
+
data->state= state;
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
}
-static void button_activate_init(bContext *C, ARegion *ar, wmOperator *op, uiBut *but, uiBut *lastbut)
+static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type)
{
- uiActivateBut *data;
+ uiHandleButtonData *data;
/* setup struct */
- data= MEM_callocN(sizeof(uiActivateBut), "uiActivateBut");
+ data= MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
+ data->window= C->window;
data->region= ar;
- data->operator= op;
data->interactive= 0;
data->state = BUTTON_STATE_INIT;
- op->customdata= data;
/* activate button */
but->flag |= UI_ACTIVE;
- but->activate= data;
-
- if(but == lastbut)
- data->tooltipdisabled= 1;
+ but->active= data;
/* we disable auto_open in the block after a threshold, because we still
* want to allow auto opening adjacent menus even if no button is activated
* inbetween going over to the other button, but only for a short while */
- if(!lastbut && but->block->auto_open)
+ if(type == BUTTON_ACTIVATE_OVER && but->block->auto_open)
if(but->block->auto_open_last+BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer())
but->block->auto_open= 0;
- if(but->block->flag & UI_BLOCK_LOOP)
- WM_event_add_modal_handler(C, &C->window->handlers, op);
- else
- /* regular button handler on area, handles mouse-exit in WM */
- WM_event_add_modal_handler(C, &C->area->handlers, op);
-
button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
- if(but->activateflag == UI_ACTIVATE_OPEN)
- button_activate_state(C, but, BUTTON_STATE_BLOCK_OPEN);
- else if(but->activateflag == UI_ACTIVATE_TEXT_EDITING)
+ if(type == BUTTON_ACTIVATE_OPEN)
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ else if(type == BUTTON_ACTIVATE_TEXT_EDITING)
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- else if(but->activateflag == UI_ACTIVATE_APPLY)
+ else if(type == BUTTON_ACTIVATE_APPLY)
button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
-
- but->activateflag= 0;
}
-static void button_activate_exit(bContext *C, uiActivateBut *data, wmOperator *op)
+static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *but, int mousemove)
{
- uiBut *but;
- uiBlock *block;
+ uiBlock *block= but->block;
- /* verify if we still have a button, can be NULL! */
- but= ui_but_find_activated(data->region, data, &block);
+ /* ensure we are in the exit state */
+ if(data->state != BUTTON_STATE_EXIT)
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
- /* stop text editing */
- if(data->state == BUTTON_STATE_TEXT_EDITING || data->state == BUTTON_STATE_TEXT_SELECTING) {
- data->cancel= 1;
- ui_textedit_end(but, data);
- }
+ /* 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;
- if(data->state == BUTTON_STATE_NUM_EDITING)
- ui_numedit_end(but, data);
-
- if(data->state == BUTTON_STATE_BLOCK_OPEN) {
- ui_blockopen_end(C, but, data);
+ handle= block->handle;
+ handle->butretval= data->retval;
+ handle->menuretval= UI_RETURN_OK;
}
- if(but) {
- /* if someone is expecting a message */
- if(but->block->handle && !(but->block->flag & UI_BLOCK_KEEP_OPEN) && !data->cancel) {
- uiMenuBlockHandle *handle;
-
- handle= but->block->handle;
- handle->butretval= data->retval;
- if(data->blockretval) {
- handle->blockretval= data->blockretval;
-
- /* if we got a cancel from a block menu, then also cancel this
- * button, we set that here to instead of in do_BLOCK to make
- * a distinction with cancel after lost highlight for example */
- if(data->blockretval == UI_RETURN_CANCEL)
- data->cancel= 1;
- }
- else
- handle->blockretval= UI_RETURN_OK;
+ /* apply the button action or value */
+ ui_apply_button(block, but, data, 0);
- WM_event_add_message(C->wm, handle, 0);
- }
-
- /* apply the button action or value */
- ui_apply_button(block, but, data, 0);
-
- /* clean up button */
- but->activate= NULL;
- but->flag &= ~(UI_ACTIVE|UI_SELECT);
- }
-
- /* redraw */
- WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
+ /* disable tooltips until mousemove */
+ ui_blocks_set_tooltips(data->region, 0);
/* clean up */
- button_disable_timers(C, data);
-
if(data->str)
MEM_freeN(data->str);
if(data->origstr)
MEM_freeN(data->origstr);
- if(data->flashtimer)
- WM_event_remove_window_timer(C->window, data->flashtimer);
-
- MEM_freeN(op->customdata);
- op->customdata= NULL;
-}
-static int button_activate_try_init(bContext *C, ARegion *ar, wmOperator *op, wmEvent *event, uiBut *lastbut)
-{
- uiBut *but;
+ /* clean up button */
+ MEM_freeN(but->active);
+ but->active= NULL;
+ but->flag &= ~(UI_ACTIVE|UI_SELECT);
- /* try to activate a button */
- if(!ar)
- return OPERATOR_PASS_THROUGH;
-
- if(ui_but_find_activated(ar, NULL, NULL))
- return OPERATOR_PASS_THROUGH;
-
- but= ui_but_find_signal(ar, NULL, NULL);
+ /* redraw */
+ WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
- if(!but)
- but= ui_but_find_mouse_over(ar, event->x, event->y, NULL);
+ /* adds empty mousemove in queue for re-init handler, in case mouse is
+ * still over a button. we cannot just check for this ourselfs because
+ * at this point the mouse may be over a button in another region */
+ if(mousemove)
+ WM_event_add_mousemove(C);
+}
- if(lastbut && but && but!=lastbut)
- return OPERATOR_PASS_THROUGH;
+void ui_button_active_cancel(const bContext *C, uiBut *but)
+{
+ uiHandleButtonData *data;
- if(but && !but->activate) {
- button_activate_init(C, ar, op, but, lastbut);
- return OPERATOR_RUNNING_MODAL;
+ /* this gets called when the button somehow disappears while it is still
+ * active, this is bad for user interaction, but we need to handle this
+ * case cleanly anyway in case it happens */
+ if(but->active) {
+ data= but->active;
+ data->cancel= 1;
+ button_activate_exit((bContext*)C, data, but, 0);
}
-
- return OPERATOR_PASS_THROUGH;
}
-static int button_activate_try_exit(bContext *C, wmOperator *op, wmEvent *event)
+/************** handle activating a button *************/
+
+static int ui_handle_button_over(bContext *C, wmEvent *event, ARegion *ar)
{
- ARegion *ar;
- uiActivateBut *data;
uiBut *but;
- data= op->customdata;
- ar= data->region;
+ if(event->type == MOUSEMOVE) {
+ but= ui_but_find_mouse_over(ar, event->x, event->y);
- but= ui_but_find_activated(data->region, data, NULL);
-
- /* exit the current button */
- button_activate_exit(C, op->customdata, op);
-
- /* adds empty mousemove in queue for re-init operator (if mouse is still over button) */
- WM_event_add_mousemove(C);
-
- return 1;
-}
+ if(but)
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ }
-static int button_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- return button_activate_try_init(C, C->region, op, event, NULL);
+ return WM_UI_HANDLER_CONTINUE;
}
-static int button_activate_cancel(bContext *C, wmOperator *op)
+static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type)
{
- uiActivateBut *data;
+ uiBut *oldbut;
+ uiHandleButtonData *data;
- data= op->customdata;
- data->cancel= 1;
- button_activate_exit(C, op->customdata, op);
+ oldbut= ui_but_find_activated(ar);
+ if(oldbut) {
+ data= oldbut->active;
+ data->cancel= 1;
+ button_activate_exit(C, data, oldbut, 0);
+ }
- return OPERATOR_CANCELLED;
+ button_activate_init(C, ar, but, type);
}
-static int button_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
+/************ handle events for an activated button ***********/
+
+static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
{
- uiActivateBut *data;
- uiBut *but;
+ uiHandleButtonData *data;
uiBlock *block;
- int handled= 0;
+ ARegion *ar;
+ uiBut *postbut;
+ uiButtonActivateType posttype;
+ int retval, mx, my;
- data= op->customdata;
- /* XXX (for brecht) this happens when cancel() frees, and modal handler still runs */
- if(data==NULL)
- return OPERATOR_FINISHED;
-
- /* check if the button dissappeared somehow */
- if(!(but= ui_but_find_activated(data->region, data, &block))) {
- data->cancel= 1;
- button_activate_try_exit(C, op, event);
- return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
- }
+ data= but->active;
+ block= but->block;
+ ar= data->region;
+ retval= WM_UI_HANDLER_CONTINUE;
+
if(data->state == BUTTON_STATE_HIGHLIGHT) {
switch(event->type) {
case MOUSEMOVE:
/* verify if we are still over the button, if not exit */
- but= ui_but_find_mouse_over(data->region, event->x, event->y, &block);
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(ar, block, &mx, &my);
- if(!but || but->activate != data) {
+ if(!ui_but_contains_pt(but, mx, my)) {
data->cancel= 1;
- if(button_activate_try_exit(C, op, event))
- return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
- else
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
}
+ else if(event->x!=event->prevx || event->y!=event->prevy) {
+ /* re-enable tooltip on mouse move */
+ ui_blocks_set_tooltips(ar, 1);
+ button_tooltip_timer_start(but);
+ }
+
break;
case TIMER: {
/* handle tooltip timer */
if(event->customdata == data->tooltiptimer) {
+ WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ data->tooltiptimer= NULL;
+
if(!data->tooltip) {
data->tooltip= ui_tooltip_create(C, data->region, but);
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
}
-
- WM_event_remove_window_timer(C->window, data->tooltiptimer);
- data->tooltiptimer= NULL;
}
+ /* handle menu auto open timer */
else if(event->customdata == data->autoopentimer) {
- button_activate_state(C, but, BUTTON_STATE_BLOCK_OPEN);
-
- WM_event_remove_window_timer(C->window, data->autoopentimer);
+ WM_event_remove_window_timer(data->window, data->autoopentimer);
data->autoopentimer= NULL;
+
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(ar, block, &mx, &my);
+
+ if(ui_but_contains_pt(but, mx, my))
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
}
+ retval= WM_UI_HANDLER_CONTINUE;
break;
default:
- handled= ui_do_button(C, block, but, event);
+ /* handle button type specific events */
+ retval= ui_do_button(C, block, but, event);
}
}
-
}
else if(data->state == BUTTON_STATE_WAIT_RELEASE) {
switch(event->type) {
case MOUSEMOVE:
/* deselect the button when moving the mouse away */
- but= ui_but_find_mouse_over(data->region, event->x, event->y, &block);
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(ar, block, &mx, &my);
- if(but && but->activate == data) {
+ if(ui_but_contains_pt(but, mx, my)) {
if(!(but->flag & UI_SELECT)) {
but->flag |= UI_SELECT;
+ data->cancel= 0;
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
}
}
else {
- but= ui_but_find_activated(data->region, data, &block);
if(but->flag & UI_SELECT) {
but->flag &= ~UI_SELECT;
+ data->cancel= 1;
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
}
}
break;
+ default:
+ /* otherwise catch mouse release event */
+ ui_do_button(C, block, but, event);
+ break;
}
- ui_do_button(C, block, but, event);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
else if(data->state == BUTTON_STATE_WAIT_FLASH) {
switch(event->type) {
@@ -2995,62 +2968,69 @@ static int button_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
+
+ retval= WM_UI_HANDLER_CONTINUE;
}
- else if(data->state == BUTTON_STATE_BLOCK_OPEN) {
+ else if(data->state == BUTTON_STATE_MENU_OPEN) {
switch(event->type) {
case MOUSEMOVE: {
- uiBut *bt= ui_but_find_mouse_over(data->region, event->x, event->y, &block);
+ uiBut *bt= ui_but_find_mouse_over(ar, event->x, event->y);
- if(bt && bt->activate != data) {
+ if(bt && bt->active != data) {
data->cancel= 1;
- if(button_activate_try_exit(C, op, event))
- return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
- else
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
}
break;
}
}
ui_do_button(C, block, but, event);
- handled= 0;
+ retval= WM_UI_HANDLER_CONTINUE;
}
else {
ui_do_button(C, block, but, event);
- handled= 1;
+ retval= WM_UI_HANDLER_BREAK;
}
if(data->state == BUTTON_STATE_EXIT) {
- if(button_activate_try_exit(C, op, event))
- return OPERATOR_CANCELLED|(handled==0? OPERATOR_PASS_THROUGH: 0);
- else
- return OPERATOR_RUNNING_MODAL|(handled==0? OPERATOR_PASS_THROUGH: 0);
+ postbut= data->postbut;
+ posttype= data->posttype;
+
+ button_activate_exit(C, data, but, (postbut == NULL));
+
+ /* for jumping to the next button with tab while text editing */
+ if(postbut)
+ button_activate_init(C, ar, postbut, posttype);
}
- if(handled)
- return OPERATOR_RUNNING_MODAL;
- else
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ return retval;
}
-static int button_activate_poll(bContext *C)
+static void ui_handle_button_closed_submenu(bContext *C, uiBut *but)
{
- if(C->region==NULL) return 0;
- if(C->region->uiblocks.first==NULL) return 0;
- return 1;
-}
+ uiHandleButtonData *data;
+ uiMenuBlockHandle *handle;
-void ED_UI_OT_button_activate(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Button Highlight";
- ot->idname= "ED_UI_OT_button_activate";
+ data= but->active;
+ handle= data->menu->handle;
+
+ /* copy over return values from the closing menu */
+ if(handle->menuretval == UI_RETURN_OK) {
+ if(but->type == COL)
+ VECCOPY(data->vec, handle->retvec)
+ else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
+ data->value= handle->retvalue;
+ }
- /* api callbacks */
- ot->invoke= button_activate_invoke;
- ot->cancel= button_activate_cancel;
- ot->modal= button_activate_modal;
- ot->poll= button_activate_poll;
+ /* 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)
+ data->cancel= 1;
+
+ button_activate_exit(C, data, but, 1);
+ }
+ else if(handle->menuretval == UI_RETURN_OUT)
+ button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
}
/* ******************** menu navigation helpers ************** */
@@ -3097,84 +3077,7 @@ static uiBut *ui_but_last(uiBlock *block)
return NULL;
}
-/* ********************** menu navigate operator *****************************
- * this operator is invoked when the block/region is opened and cancelled when
- * it closes, it blocks nearly all events. this operator will not close the
- * actual block, instead this must be done by the button activate operator when
- * it receives the result message */
-
-typedef struct uiBlockHandle {
- ARegion *region;
-
- int towardsx, towardsy;
- double towardstime;
- int dotowards;
-} uiBlockHandle;
-
-static int menu_block_handle_cancel(bContext *C, wmOperator *op)
-{
- if(op->customdata) {
- MEM_freeN(op->customdata);
- op->customdata= NULL;
- }
-
- return OPERATOR_CANCELLED;
-}
-
-static void menu_block_handle_return(bContext *C, wmOperator *op, uiBlock *block, int retval)
-{
- uiMenuBlockHandle *handle;
-
- handle= block->handle;
- handle->blockretval= retval;
- handle->butretval= 0;
-
- WM_event_add_message(C->wm, handle, 0);
- menu_block_handle_cancel(C, op);
-}
-
-static int menu_block_handle_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- uiMenuBlockHandle *handle;
-
- handle= MEM_callocN(sizeof(uiBlockHandle), "uiBlockHandle");
- handle->region= C->region;
-
- op->customdata= handle;
- WM_event_add_modal_handler(C, &C->window->handlers, op);
-
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
-}
-
-static int menu_block_handle_block_open(uiBlock *block)
-{
- uiBut *but;
- uiActivateBut *data;
-
- for(but=block->buttons.first; but; but=but->next) {
- data= but->activate;
-
- if(data && data->state == BUTTON_STATE_BLOCK_OPEN)
- return 1;
- }
-
- return 0;
-}
-
-/* moves focus on button/menu from mousemove-based to hotkey */
-static void menu_block_handle_activate_button(bContext *C, wmEvent *event, ARegion *butregion, uiBut *but, int activateflag)
-{
- wmOperatorType *ot;
-
- ot= WM_operatortype_find("ED_UI_OT_button_activate");
-
- // XXX WM_operator_cancel(C, &butregion->modalops, ot);
- but->activateflag= activateflag;
-
- SWAP(ARegion*, C->region, butregion); /* XXX 2.50 bad state manipulation? */
- WM_operator_invoke(C, ot, event);
- SWAP(ARegion*, C->region, butregion);
-}
+/* ************************* menu handling *******************************/
/* function used to prevent loosing the open menu when using nested pulldowns,
* when moving mouse towards the pulldown menu over other buttons that could
@@ -3185,334 +3088,444 @@ static void menu_block_handle_activate_button(bContext *C, wmEvent *event, ARegi
* - only for 1 second
*/
-static void ui_mouse_motion_towards_init(uiBlockHandle *bhandle, int mx, int my)
+static void ui_mouse_motion_towards_init(uiHandleMenuData *menu, int mx, int my)
{
- if(!bhandle->dotowards) {
- bhandle->dotowards= 1;
- bhandle->towardsx= mx;
- bhandle->towardsy= my;
- bhandle->towardstime= PIL_check_seconds_timer();
+ if(!menu->dotowards) {
+ menu->dotowards= 1;
+ menu->towardsx= mx;
+ menu->towardsy= my;
+ menu->towardstime= PIL_check_seconds_timer();
}
}
-static int ui_mouse_motion_towards_check(uiBlock *block, uiBlockHandle *bhandle, int mx, int my)
+static int ui_mouse_motion_towards_check(uiBlock *block, uiHandleMenuData *menu, int mx, int my)
{
int fac, dx, dy, domx, domy;
- if(!bhandle->dotowards) return 0;
+ if(!menu->dotowards) return 0;
if((block->direction & UI_TOP) || (block->direction & UI_DOWN)) {
- bhandle->dotowards= 0;
- return bhandle->dotowards;
+ menu->dotowards= 0;
+ return menu->dotowards;
}
/* calculate dominant direction */
- domx= (-bhandle->towardsx + (block->maxx+block->minx)/2);
- domy= (-bhandle->towardsy + (block->maxy+block->miny)/2);
+ domx= (-menu->towardsx + (block->maxx+block->minx)/2);
+ domy= (-menu->towardsy + (block->maxy+block->miny)/2);
/* we need some accuracy */
if(abs(domx) < 4) {
- bhandle->dotowards= 0;
- return bhandle->dotowards;
+ menu->dotowards= 0;
+ return menu->dotowards;
}
/* check direction */
- dx= mx - bhandle->towardsx;
- dy= my - bhandle->towardsy;
+ dx= mx - menu->towardsx;
+ dy= my - menu->towardsy;
/* threshold */
if(abs(dx)+abs(dy) > 4) {
/* menu to right */
if(domx>0) {
- fac= (mx - bhandle->towardsx)*( bhandle->towardsy - (int)(block->maxy+20)) +
- (my - bhandle->towardsy)*(-bhandle->towardsx + (int)block->minx);
- if(fac>0) bhandle->dotowards= 0;
+ fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->maxy+20)) +
+ (my - menu->towardsy)*(-menu->towardsx + (int)block->minx);
+ if(fac>0) menu->dotowards= 0;
- fac= (mx - bhandle->towardsx)*( bhandle->towardsy - (int)(block->miny-20)) +
- (my - bhandle->towardsy)*(-bhandle->towardsx + (int)block->minx);
- if(fac<0) bhandle->dotowards= 0;
+ fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->miny-20)) +
+ (my - menu->towardsy)*(-menu->towardsx + (int)block->minx);
+ if(fac<0) menu->dotowards= 0;
}
else {
- fac= (mx - bhandle->towardsx)*( bhandle->towardsy - (int)(block->maxy+20)) +
- (my - bhandle->towardsy)*(-bhandle->towardsx + (int)block->maxx);
- if(fac<0) bhandle->dotowards= 0;
+ fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->maxy+20)) +
+ (my - menu->towardsy)*(-menu->towardsx + (int)block->maxx);
+ if(fac<0) menu->dotowards= 0;
- fac= (mx - bhandle->towardsx)*( bhandle->towardsy - (int)(block->miny-20)) +
- (my - bhandle->towardsy)*(-bhandle->towardsx + (int)block->maxx);
- if(fac>0) bhandle->dotowards= 0;
+ fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->miny-20)) +
+ (my - menu->towardsy)*(-menu->towardsx + (int)block->maxx);
+ if(fac>0) menu->dotowards= 0;
}
}
/* 1 second timer */
- if(PIL_check_seconds_timer() - bhandle->towardstime > BUTTON_MOUSE_TOWARDS_THRESH)
- bhandle->dotowards= 0;
+ if(PIL_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH)
+ menu->dotowards= 0;
- return bhandle->dotowards;
+ return menu->dotowards;
}
-static int menu_block_handle_modal(bContext *C, wmOperator *op, wmEvent *event)
+int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, int topmenu)
{
ARegion *ar;
uiBlock *block;
uiBut *but, *bt;
- uiBlockHandle *bhandle;
- int inside, act, count, mx, my, handled;
+ uiMenuBlockHandle *handle;
+ int inside, act, count, mx, my, retval;
- bhandle= op->customdata;
- /* XXX (for brecht) this happens when cancel() frees, and modal handler still runs */
- if(bhandle==NULL)
- return OPERATOR_FINISHED;
-
- ar= bhandle->region;
+ ar= menu->handle->region;
block= ar->uiblocks.first;
-
- /* XXX (for brecht) this happens when click on menu */
- if(block==NULL)
- return OPERATOR_FINISHED;
+ handle= menu->handle;
act= 0;
- handled= 0;
-
- /* if we have another block opened, we shouldn't do anything
- * until that block is closed again, otherwise we interfere */
- if(menu_block_handle_block_open(block))
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ retval= WM_UI_HANDLER_CONTINUE;
mx= event->x;
my= event->y;
ui_window_to_block(ar, block, &mx, &my);
- /* for ui_mouse_motion_towards_block */
- if(event->type == MOUSEMOVE)
- ui_mouse_motion_towards_init(bhandle, mx, my);
-
/* check if mouse is inside block */
inside= 0;
if(block->minx <= mx && block->maxx >= mx)
if(block->miny <= my && block->maxy >= my)
inside= 1;
- switch(event->type) {
- /* closing sublevels of pulldowns */
- case LEFTARROWKEY:
- if(event->val && (block->flag & UI_BLOCK_LOOP))
- if(BLI_countlist(&block->saferct) > 0)
- menu_block_handle_return(C, op, block, UI_RETURN_OUT);
+ if(topmenu && event->type != TIMER) {
+ /* for ui_mouse_motion_towards_block */
+ if(event->type == MOUSEMOVE)
+ ui_mouse_motion_towards_init(menu, mx, my);
- handled= 1;
- break;
-
- /* opening sublevels of pulldowns */
- case RIGHTARROWKEY:
- if(event->val && (block->flag & UI_BLOCK_LOOP)) {
- but= ui_but_find_activated(ar, NULL, NULL);
-
- if(!but) {
- /* no item active, we make first active */
- if(block->direction & UI_TOP) but= ui_but_last(block);
- else but= ui_but_first(block);
- }
+ switch(event->type) {
+ /* closing sublevels of pulldowns */
+ case LEFTARROWKEY:
+ if(event->val && (block->flag & UI_BLOCK_LOOP))
+ if(BLI_countlist(&block->saferct) > 0)
+ handle->menuretval= UI_RETURN_OUT;
- if(but && but->type==BLOCK)
- menu_block_handle_activate_button(C, event, ar, but, UI_ACTIVATE_OPEN);
- }
- handled= 1;
- break;
-
- case UPARROWKEY:
- case DOWNARROWKEY:
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- /* arrowkeys: only handle for block_loop blocks */
- if(inside || (block->flag & UI_BLOCK_LOOP)) {
- if(event->val) {
- but= ui_but_find_activated(ar, NULL, NULL);
-
- if(but) {
- if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) {
- if(block->direction & UI_TOP) but= ui_but_next(but);
- else but= ui_but_prev(but);
- }
- else {
- if(block->direction & UI_TOP) but= ui_but_prev(but);
- else but= ui_but_next(but);
- }
+ retval= WM_UI_HANDLER_BREAK;
+ break;
- if(but)
- menu_block_handle_activate_button(C, event, ar, but, UI_ACTIVATE);
- }
+ /* opening sublevels of pulldowns */
+ case RIGHTARROWKEY:
+ if(event->val && (block->flag & UI_BLOCK_LOOP)) {
+ but= ui_but_find_activated(ar);
if(!but) {
- if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) {
- if(block->direction & UI_TOP) bt= ui_but_first(block);
- else bt= ui_but_last(block);
- }
- else {
- if(block->direction & UI_TOP) bt= ui_but_last(block);
- else bt= ui_but_first(block);
+ /* no item active, we make first active */
+ if(block->direction & UI_TOP) but= ui_but_last(block);
+ else but= ui_but_first(block);
+ }
+
+ if(but && but->type==BLOCK)
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
+ }
+
+ retval= WM_UI_HANDLER_BREAK;
+ break;
+
+ case UPARROWKEY:
+ case DOWNARROWKEY:
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE:
+ /* arrowkeys: only handle for block_loop blocks */
+ if(inside || (block->flag & UI_BLOCK_LOOP)) {
+ if(event->val) {
+ but= ui_but_find_activated(ar);
+
+ if(but) {
+ if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) {
+ if(block->direction & UI_TOP) but= ui_but_next(but);
+ else but= ui_but_prev(but);
+ }
+ else {
+ if(block->direction & UI_TOP) but= ui_but_prev(but);
+ else but= ui_but_next(but);
+ }
+
+ if(but)
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
}
- if(bt)
- menu_block_handle_activate_button(C, event, ar, bt, UI_ACTIVATE);
+ if(!but) {
+ if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) {
+ if(block->direction & UI_TOP) bt= ui_but_first(block);
+ else bt= ui_but_last(block);
+ }
+ else {
+ if(block->direction & UI_TOP) bt= ui_but_last(block);
+ else bt= ui_but_first(block);
+ }
+
+ if(bt)
+ ui_handle_button_activate(C, ar, bt, BUTTON_ACTIVATE);
+ }
}
}
- }
- handled= 1;
- break;
- case ONEKEY: case PAD1:
- act= 1;
- case TWOKEY: case PAD2:
- if(act==0) act= 2;
- case THREEKEY: case PAD3:
- if(act==0) act= 3;
- case FOURKEY: case PAD4:
- if(act==0) act= 4;
- case FIVEKEY: case PAD5:
- if(act==0) act= 5;
- case SIXKEY: case PAD6:
- if(act==0) act= 6;
- case SEVENKEY: case PAD7:
- if(act==0) act= 7;
- case EIGHTKEY: case PAD8:
- if(act==0) act= 8;
- case NINEKEY: case PAD9:
- if(act==0) act= 9;
- case ZEROKEY: case PAD0:
- if(act==0) act= 10;
-
- if(block->flag & UI_BLOCK_NUMSELECT) {
- if(event->alt) act+= 10;
-
- count= 0;
- for(but= block->buttons.first; but; but= but->next) {
- int doit= 0;
-
- if(but->type!=LABEL && but->type!=SEPR)
- count++;
+ retval= WM_UI_HANDLER_BREAK;
+ break;
- /* exception for menus like layer buts, with button aligning they're not drawn in order */
- if(but->type==TOGR) {
- if(but->bitnr==act-1)
- doit= 1;
- }
- else if(count==act)
- doit=1;
+ case ONEKEY: case PAD1:
+ act= 1;
+ case TWOKEY: case PAD2:
+ if(act==0) act= 2;
+ case THREEKEY: case PAD3:
+ if(act==0) act= 3;
+ case FOURKEY: case PAD4:
+ if(act==0) act= 4;
+ case FIVEKEY: case PAD5:
+ if(act==0) act= 5;
+ case SIXKEY: case PAD6:
+ if(act==0) act= 6;
+ case SEVENKEY: case PAD7:
+ if(act==0) act= 7;
+ case EIGHTKEY: case PAD8:
+ if(act==0) act= 8;
+ case NINEKEY: case PAD9:
+ if(act==0) act= 9;
+ case ZEROKEY: case PAD0:
+ if(act==0) act= 10;
+
+ if(block->flag & UI_BLOCK_NUMSELECT) {
+ if(event->alt) act+= 10;
- if(doit) {
- menu_block_handle_activate_button(C, event, ar, but, UI_ACTIVATE_APPLY);
- break;
+ count= 0;
+ for(but= block->buttons.first; but; but= but->next) {
+ int doit= 0;
+
+ if(but->type!=LABEL && but->type!=SEPR)
+ count++;
+
+ /* exception for menus like layer buts, with button aligning they're not drawn in order */
+ if(but->type==TOGR) {
+ if(but->bitnr==act-1)
+ doit= 1;
+ }
+ else if(count==act)
+ doit=1;
+
+ if(doit) {
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_APPLY);
+ break;
+ }
}
}
- }
- handled= 1;
- break;
- }
-
- /* here we check return conditions for menus */
- if(block->flag & UI_BLOCK_LOOP) {
- /* if we click outside the block, verify if we clicked on the
- * button that opened us, otherwise we need to close */
- if(inside==0) {
- uiSafetyRct *saferct= block->saferct.first;
- if(ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) && event->val) {
- if(saferct && !BLI_in_rctf(&saferct->parent, event->x, event->y)) {
- menu_block_handle_return(C, op, block, UI_RETURN_OK);
- return OPERATOR_RUNNING_MODAL;
- }
- }
+ retval= WM_UI_HANDLER_BREAK;
+ break;
}
- /* esc cancel this and all preceding menus */
- if(event->type==ESCKEY && event->val) {
- menu_block_handle_return(C, op, block, UI_RETURN_CANCEL);
- return OPERATOR_RUNNING_MODAL;
- }
+ /* here we check return conditions for menus */
+ if(block->flag & UI_BLOCK_LOOP) {
+ /* if we click outside the block, verify if we clicked on the
+ * button that opened us, otherwise we need to close */
+ if(inside==0) {
+ uiSafetyRct *saferct= block->saferct.first;
- 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 */
- menu_block_handle_return(C, op, block, UI_RETURN_OK);
- handled= 1;
- }
- else {
- ui_mouse_motion_towards_check(block, bhandle, mx, my);
+ 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;
+ }
- /* check mouse moving outside of the menu */
- if(inside==0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) {
- uiSafetyRct *saferct;
-
- /* check for all parent rects, enables arrowkeys to be used */
- for(saferct=block->saferct.first; saferct; saferct= saferct->next) {
- /* for mouse move we only check our own rect, for other
- * events we check all preceding block rects too to make
- * arrow keys navigation work */
- if(event->type!=MOUSEMOVE || saferct==block->saferct.first) {
- if(BLI_in_rctf(&saferct->parent, (float)event->x, (float)event->y))
- break;
- if(BLI_in_rctf(&saferct->safety, (float)event->x, (float)event->y))
- break;
+ if(handle->menuretval);
+ else if(event->type==ESCKEY && event->val) {
+ /* esc cancels this and all preceding menus */
+ handle->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;
+ }
+ else {
+ ui_mouse_motion_towards_check(block, menu, mx, my);
+
+ /* check mouse moving outside of the menu */
+ if(inside==0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) {
+ uiSafetyRct *saferct;
+
+ /* check for all parent rects, enables arrowkeys to be used */
+ for(saferct=block->saferct.first; saferct; saferct= saferct->next) {
+ /* for mouse move we only check our own rect, for other
+ * events we check all preceding block rects too to make
+ * arrow keys navigation work */
+ if(event->type!=MOUSEMOVE || saferct==block->saferct.first) {
+ if(BLI_in_rctf(&saferct->parent, (float)event->x, (float)event->y))
+ break;
+ if(BLI_in_rctf(&saferct->safety, (float)event->x, (float)event->y))
+ break;
+ }
}
- }
- /* strict check, and include the parent rect */
- if(!bhandle->dotowards && !saferct) {
- menu_block_handle_return(C, op, block, UI_RETURN_OK);
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ /* 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;
+ else if(menu->dotowards && event->type==MOUSEMOVE)
+ retval= WM_UI_HANDLER_BREAK;
}
-
- if(bhandle->dotowards && event->type==MOUSEMOVE)
- handled= 1;
}
}
}
- /* we pass on events only when the mouse pointer is inside, this ensures
- * events only go to handlers inside this region, and no other region.
- * that's an indirect way to get this behavior, maybe it should be done
- * in a more explicit way somewhow. */
- if(inside && !handled)
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ /* 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) {
+ but= ui_but_find_activated(ar);
+
+ if(but)
+ retval= ui_handle_button_event(C, event, but);
+ else
+ retval= ui_handle_button_over(C, event, ar);
+ }
+
+ /* 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)
+ return WM_UI_HANDLER_CONTINUE;
+ else if(inside)
+ return WM_UI_HANDLER_BREAK;
else
- return OPERATOR_RUNNING_MODAL;
+ return retval;
}
-static int menu_block_handle_poll(bContext *C)
+static int ui_handle_menu_closed_submenu(bContext *C, uiHandleMenuData *menu)
{
+ ARegion *ar;
+ uiBut *but;
uiBlock *block;
+ uiHandleButtonData *data;
+ uiMenuBlockHandle *handle, *subhandle;
- if(C->region==NULL) return 0;
- block= C->region->uiblocks.first;
- if(!block) return 0;
+ ar= menu->handle->region;
+ block= ar->uiblocks.first;
+ handle= menu->handle;
+
+ but= ui_but_find_activated(ar);
+ data= but->active;
+ subhandle= data->menu->handle;
+
+ if(subhandle->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(!(block->flag & UI_BLOCK_KEEP_OPEN)) {
+ handle->menuretval= subhandle->menuretval;
+ handle->butretval= data->retval;
+ }
+ }
- return 1;
+ /* now let activated button in this menu exit, which
+ * will actually close the submenu too */
+ ui_handle_button_closed_submenu(C, but);
+ }
+
+ if(handle->menuretval)
+ return WM_UI_HANDLER_CONTINUE;
+ else
+ return WM_UI_HANDLER_BREAK;
}
-void ED_UI_OT_menu_block_handle(wmOperatorType *ot)
+static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiHandleMenuData *menu)
{
- /* identifiers */
- ot->name= "Menu Block Handle";
- ot->idname= "ED_UI_OT_menu_block_handle";
-
- /* api callbacks */
- ot->invoke= menu_block_handle_invoke;
- ot->modal= menu_block_handle_modal;
- ot->cancel= menu_block_handle_cancel;
- ot->poll= menu_block_handle_poll;
+ uiBut *but;
+ uiHandleButtonData *data;
+ uiHandleMenuData *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);
+ data= (but)? but->active: NULL;
+ submenu= (data)? data->menu: NULL;
+
+ if(submenu)
+ retval= ui_handle_menus_recursive(C, event, submenu);
+
+ /* now handle events for our own menu */
+ if(retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
+ if(submenu && submenu->handle->menuretval)
+ retval= ui_handle_menu_closed_submenu(C, menu);
+ else
+ retval= ui_handle_menu_event(C, event, menu, (submenu == NULL));
+ }
+
+ return retval;
}
-/* ************************** registration **********************************/
+/* *************** UI event handlers **************** */
+
+static int ui_handler_region(bContext *C, wmEvent *event)
+{
+ ARegion *ar;
+ uiBut *but;
+ int retval;
+
+ /* here we handle buttons at the region level, non-modal */
+ ar= C->region;
+ retval= WM_UI_HANDLER_CONTINUE;
+
+ if(ar==NULL) return retval;
+ if(ar->uiblocks.first==NULL) return retval;
+
+ /* either handle events for already activated button or try to activate */
+ but= ui_but_find_activated(ar);
+
+ if(but)
+ retval= ui_handle_button_event(C, event, but);
+ else
+ retval= ui_handle_button_over(C, event, ar);
+
+ /* re-enable tooltips */
+ if(event->type == MOUSEMOVE && (event->x!=event->prevx || event->y!=event->prevy))
+ ui_blocks_set_tooltips(ar, 1);
+
+ return retval;
+}
-void UI_operatortypes(void)
+static void ui_handler_remove_region(bContext *C)
{
- WM_operatortype_append(ED_UI_OT_button_activate);
- WM_operatortype_append(ED_UI_OT_menu_block_handle);
+ ARegion *ar;
+
+ ar= C->region;
+ if(ar==NULL) return;
+
+ uiFreeBlocks(C, &ar->uiblocks);
}
-void UI_keymap(wmWindowManager *wm)
+static int ui_handler_window(bContext *C, wmEvent *event)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Interface", 0, 0);
+ ARegion *ar;
+ uiBut *but;
+ uiHandleButtonData *data;
+ int retval;
+
+ /* 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) {
+ data= but->active;
+
+ if(data->state == BUTTON_STATE_MENU_OPEN) {
+ /* handle events for menus and their buttons recursively,
+ * this will handle events from the top to the bottom menu */
+ retval= ui_handle_menus_recursive(C, event, data->menu);
- WM_keymap_add_item(keymap, "ED_UI_OT_button_activate", MOUSEMOVE, 0, 0, 0);
+ /* handle events for the activated button */
+ if(retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
+ if(data->menu->handle->menuretval)
+ ui_handle_button_closed_submenu(C, but);
+ else
+ ui_handle_button_event(C, event, but);
+ }
+ }
+ else {
+ /* handle events for the activated button */
+ ui_handle_button_event(C, event, but);
+ }
+ }
+
+ /* re-enable tooltips */
+ if(event->type == MOUSEMOVE && (event->x!=event->prevx || event->y!=event->prevy))
+ ui_blocks_set_tooltips(ar, 1);
+
+ /* we block all events, this is modal interaction */
+ return WM_UI_HANDLER_BREAK;
+}
+
+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);
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index fec3038ca88..2154236cc59 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -590,15 +590,9 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
}
}
-static void ui_block_region_free(ARegion *ar)
-{
- uiFreeBlocks(&ar->uiblocks);
-}
-
uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockFuncFP block_func, void *arg)
{
static ARegionType type;
- ListBase *keymap= WM_keymap_listbase(C->wm, "Interface", 0, 0);
ARegion *ar;
uiBlock *block;
uiBut *bt;
@@ -613,16 +607,15 @@ uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *
memset(&type, 0, sizeof(ARegionType));
type.draw= ui_block_region_draw;
- type.free= ui_block_region_free;
ar->type= &type;
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ UI_add_region_handlers(&ar->handlers);
handle->region= ar;
ar->regiondata= handle;
/* create ui block */
- block= block_func(C->window, handle, arg);
+ block= block_func(C, handle, arg);
block->handle= handle;
/* if this is being created from a button */
@@ -674,10 +667,6 @@ uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *
WM_event_add_notifier(C, WM_NOTE_SCREEN_CHANGED, 0, NULL);
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
- SWAP(ARegion*, C->region, ar); /* XXX 2.50 bad context swapping */
- WM_operator_invoke(C, WM_operatortype_find("ED_UI_OT_menu_block_handle"), NULL);
- SWAP(ARegion*, C->region, ar);
-
return handle;
}
@@ -692,7 +681,7 @@ void ui_menu_block_free(bContext *C, uiMenuBlockHandle *handle)
/***************************** Menu Button ***************************/
-uiBlock *ui_block_func_MENU(wmWindow *window, uiMenuBlockHandle *handle, void *arg_but)
+uiBlock *ui_block_func_MENU(bContext *C, uiMenuBlockHandle *handle, void *arg_but)
{
uiBut *but= arg_but;
uiBlock *block;
@@ -703,7 +692,7 @@ uiBlock *ui_block_func_MENU(wmWindow *window, uiMenuBlockHandle *handle, void *a
int width, height, boxh, columns, rows, startx, starty, x1, y1, xmax, a;
/* create the block */
- block= uiBeginBlock(window, handle->region, "menu", UI_EMBOSSP, UI_HELV);
+ block= uiBeginBlock(C, handle->region, "menu", UI_EMBOSSP, UI_HELV);
block->dt= UI_EMBOSSP;
block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT;
block->themecol= TH_MENU_ITEM;
@@ -803,18 +792,18 @@ uiBlock *ui_block_func_MENU(wmWindow *window, uiMenuBlockHandle *handle, void *a
block->buttons= lb;
block->direction= UI_TOP;
- uiEndBlock(block);
+ uiEndBlock(C, block);
return block;
}
-uiBlock *ui_block_func_ICONROW(wmWindow *window, uiMenuBlockHandle *handle, void *arg_but)
+uiBlock *ui_block_func_ICONROW(bContext *C, uiMenuBlockHandle *handle, void *arg_but)
{
uiBut *but= arg_but;
uiBlock *block;
int a;
- block= uiBeginBlock(window, handle->region, "menu", UI_EMBOSSP, UI_HELV);
+ block= uiBeginBlock(C, handle->region, "menu", UI_EMBOSSP, UI_HELV);
block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT;
block->themecol= TH_MENU_ITEM;
@@ -824,19 +813,19 @@ uiBlock *ui_block_func_ICONROW(wmWindow *window, uiMenuBlockHandle *handle, void
block->direction= UI_TOP;
- uiEndBlock(block);
+ uiEndBlock(C, block);
return block;
}
-uiBlock *ui_block_func_ICONTEXTROW(wmWindow *window, uiMenuBlockHandle *handle, void *arg_but)
+uiBlock *ui_block_func_ICONTEXTROW(bContext *C, uiMenuBlockHandle *handle, void *arg_but)
{
uiBut *but= arg_but;
uiBlock *block;
MenuData *md;
int width, xmax, ypos, a;
- block= uiBeginBlock(window, handle->region, "menu", UI_EMBOSSP, UI_HELV);
+ block= uiBeginBlock(C, handle->region, "menu", UI_EMBOSSP, UI_HELV);
block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT;
block->themecol= TH_MENU_ITEM;
@@ -885,7 +874,7 @@ uiBlock *ui_block_func_ICONTEXTROW(wmWindow *window, uiMenuBlockHandle *handle,
block->direction= UI_TOP;
uiBoundsBlock(block, 3);
- uiEndBlock(block);
+ uiEndBlock(C, block);
return block;
}
@@ -1234,14 +1223,14 @@ void uiBlockPickerButtons(uiBlock *block, float *col, float *hsv, float *old, ch
uiBlockEndAlign(block);
}
-uiBlock *ui_block_func_COL(wmWindow *window, uiMenuBlockHandle *handle, void *arg_but)
+uiBlock *ui_block_func_COL(bContext *C, uiMenuBlockHandle *handle, void *arg_but)
{
uiBut *but= arg_but;
uiBlock *block;
static float hsvcol[3], oldcol[3];
static char hexcol[128];
- block= uiBeginBlock(window, handle->region, "colorpicker", UI_EMBOSS, UI_HELV);
+ block= uiBeginBlock(C, handle->region, "colorpicker", UI_EMBOSS, UI_HELV);
block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
block->themecol= TH_BUT_NUM;
@@ -1294,7 +1283,7 @@ typedef struct uiPupMenuInfo {
int maxrow;
} uiPupMenuInfo;
-uiBlock *ui_block_func_PUPMENU(wmWindow *window, uiMenuBlockHandle *handle, void *arg_info)
+uiBlock *ui_block_func_PUPMENU(bContext *C, uiMenuBlockHandle *handle, void *arg_info)
{
uiBlock *block;
uiPupMenuInfo *info;
@@ -1309,7 +1298,7 @@ uiBlock *ui_block_func_PUPMENU(wmWindow *window, uiMenuBlockHandle *handle, void
height= 0;
/* block stuff first, need to know the font */
- block= uiBeginBlock(window, handle->region, "menu", UI_EMBOSSP, UI_HELV);
+ block= uiBeginBlock(C, handle->region, "menu", UI_EMBOSSP, UI_HELV);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_NUMSELECT);
block->themecol= TH_MENU_ITEM;
@@ -1336,7 +1325,7 @@ uiBlock *ui_block_func_PUPMENU(wmWindow *window, uiMenuBlockHandle *handle, void
width+= 10;
if (width<50) width=50;
- wm_window_get_size(window, &xmax, &ymax);
+ wm_window_get_size(C->window, &xmax, &ymax);
/* set first item */
lastselected= 0;
@@ -1428,7 +1417,7 @@ uiBlock *ui_block_func_PUPMENU(wmWindow *window, uiMenuBlockHandle *handle, void
}
uiBoundsBlock(block, 1);
- uiEndBlock(block);
+ uiEndBlock(C, block);
menudata_free(md);
@@ -1455,7 +1444,7 @@ uiBlock *ui_block_func_PUPMENU(wmWindow *window, uiMenuBlockHandle *handle, void
return block;
}
-uiBlock *ui_block_func_PUPMENUCOL(wmWindow *window, uiMenuBlockHandle *handle, void *arg_info)
+uiBlock *ui_block_func_PUPMENUCOL(bContext *C, uiMenuBlockHandle *handle, void *arg_info)
{
uiBlock *block;
uiPupMenuInfo *info;
@@ -1470,7 +1459,7 @@ uiBlock *ui_block_func_PUPMENUCOL(wmWindow *window, uiMenuBlockHandle *handle, v
height= 0;
/* block stuff first, need to know the font */
- block= uiBeginBlock(window, handle->region, "menu", UI_EMBOSSP, UI_HELV);
+ block= uiBeginBlock(C, handle->region, "menu", UI_EMBOSSP, UI_HELV);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_NUMSELECT);
block->themecol= TH_MENU_ITEM;
@@ -1508,7 +1497,7 @@ uiBlock *ui_block_func_PUPMENUCOL(wmWindow *window, uiMenuBlockHandle *handle, v
height= rows*MENU_BUTTON_HEIGHT;
if (md->title) height+= MENU_BUTTON_HEIGHT;
- wm_window_get_size(window, &xmax, &ymax);
+ wm_window_get_size(C->window, &xmax, &ymax);
/* find active item */
fvalue= handle->retvalue;
@@ -1596,7 +1585,7 @@ uiBlock *ui_block_func_PUPMENUCOL(wmWindow *window, uiMenuBlockHandle *handle, v
}
uiBoundsBlock(block, 1);
- uiEndBlock(block);
+ uiEndBlock(C, block);
#if 0
event= uiDoBlocks(&listb, 0, 1);
@@ -1646,13 +1635,13 @@ void pupmenu_free(bContext *C, uiMenuBlockHandle *handle)
/*************** Temporary Buttons Tests **********************/
-static uiBlock *test_submenu(wmWindow *window, uiMenuBlockHandle *handle, void *arg)
+static uiBlock *test_submenu(bContext *C, uiMenuBlockHandle *handle, void *arg)
{
ARegion *ar= handle->region;
uiBlock *block;
short yco= 0, menuwidth=120;
- block= uiBeginBlock(window, ar, "test_viewmenu", UI_EMBOSSP, UI_HELV);
+ 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,
@@ -1682,19 +1671,19 @@ static uiBlock *test_submenu(wmWindow *window, uiMenuBlockHandle *handle, void *
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 50);
- uiEndBlock(block);
+ uiEndBlock(C, block);
return block;
}
-static uiBlock *test_viewmenu(wmWindow *window, uiMenuBlockHandle *handle, void *arg_area)
+static uiBlock *test_viewmenu(bContext *C, uiMenuBlockHandle *handle, void *arg_area)
{
ScrArea *area= arg_area;
ARegion *ar= handle->region;
uiBlock *block;
short yco= 0, menuwidth=120;
- block= uiBeginBlock(window, ar, "test_viewmenu", UI_EMBOSSP, UI_HELV);
+ 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,
@@ -1723,6 +1712,7 @@ static uiBlock *test_viewmenu(wmWindow *window, uiMenuBlockHandle *handle, void
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) {
@@ -1734,7 +1724,7 @@ static uiBlock *test_viewmenu(wmWindow *window, uiMenuBlockHandle *handle, void
}
uiTextBoundsBlock(block, 50);
- uiEndBlock(block);
+ uiEndBlock(C, block);
return block;
}
@@ -1754,7 +1744,7 @@ void uiTestRegion(const bContext *C)
static ColorBand *coba= NULL;
#endif
- block= uiBeginBlock(C->window, C->region, "header buttons", UI_EMBOSS, UI_HELV);
+ block= uiBeginBlock(C, C->region, "header buttons", UI_EMBOSS, UI_HELV);
uiDefPulldownBut(block, test_viewmenu, C->area, "View",
13, 1, 50, 24, "");
@@ -1796,7 +1786,7 @@ void uiTestRegion(const bContext *C)
13+400+100+10, 33, 150, 30, coba, 0.0f, 1.0f, 0, 0, "");
#endif
- uiEndBlock(block);
+ uiEndBlock(C, block);
uiDrawBlock(block);
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 54bfdcf4d65..c959e1da17d 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -167,7 +167,9 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
glColor3f(fac, fac, fac);
glRecti(20, 2, 30, 12);
}
- region_draw_emboss(ar);
+
+ if(C->area)
+ region_draw_emboss(ar);
/* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */
ED_region_pixelspace(C, ar);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index d7a43680b97..e2ac4d90645 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -920,24 +920,33 @@ void ED_screens_initialize(wmWindowManager *wm)
void ED_region_exit(bContext *C, ARegion *ar)
{
+ ARegion *prevar= C->region;
+
+ C->region= ar;
WM_event_remove_handlers(C, &ar->handlers);
+ C->region= prevar;
}
void ED_area_exit(bContext *C, ScrArea *sa)
{
+ ScrArea *prevsa= C->area;
ARegion *ar;
+ C->area= sa;
for(ar= sa->regionbase.first; ar; ar= ar->next)
ED_region_exit(C, ar);
WM_event_remove_handlers(C, &sa->handlers);
+ C->area= prevsa;
}
void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
{
+ wmWindow *prevwin= C->window;
ScrArea *sa;
ARegion *ar;
+ C->window= window;
for(ar= screen->regionbase.first; ar; ar= ar->next)
ED_region_exit(C, ar);
@@ -945,6 +954,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
ED_area_exit(C, sa);
WM_event_remove_handlers(C, &window->handlers);
+ C->window= prevwin;
}
diff --git a/source/blender/editors/screen/spacetypes.c b/source/blender/editors/screen/spacetypes.c
index ec348882acb..514a459df4f 100644
--- a/source/blender/editors/screen/spacetypes.c
+++ b/source/blender/editors/screen/spacetypes.c
@@ -71,7 +71,6 @@ void ED_spacetypes_init(void)
/* register operator types for screen and all spaces */
ED_operatortypes_screen();
- UI_operatortypes();
ui_view2d_operatortypes();
spacetypes = BKE_spacetypes_list();
@@ -89,7 +88,6 @@ void ED_spacetypes_keymap(wmWindowManager *wm)
ED_keymap_screen(wm);
UI_view2d_keymap(wm);
- UI_keymap(wm);
spacetypes = BKE_spacetypes_list();
for(type=spacetypes->first; type; type=type->next)
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 4ec64a5328d..558767ce97e 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -31,6 +31,7 @@
#include "DNA_color_types.h"
#include "DNA_object_types.h"
+#include "DNA_oops_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -105,17 +106,17 @@ void UI_table_free(uiTable *table)
MEM_freeN(table);
}
-void UI_table_draw(wmWindow *window, ARegion *region, uiTable *table)
+void UI_table_draw(const bContext *C, uiTable *table)
{
uiBlock *block;
View2D *v2d;
rcti *rct, cellrct;
int y, row, col;
- v2d= &region->v2d;
+ v2d= &C->region->v2d;
rct= &table->rct;
- block= uiBeginBlock(window, region, "table outliner", UI_EMBOSST, UI_HELV);
+ block= uiBeginBlock(C, C->region, "table outliner", UI_EMBOSST, UI_HELV);
for(y=rct->ymax, row=0; y>rct->ymin; y-=ROW_HEIGHT, row++) {
if(row%2 == 0) {
@@ -141,7 +142,7 @@ void UI_table_draw(wmWindow *window, ARegion *region, uiTable *table)
for(col=0; col<table->cols; col++)
fdrawline(rct->xmin+COLUMN_WIDTH*(col+1), rct->ymin, rct->xmin+COLUMN_WIDTH*(col+1), rct->ymax);
- uiEndBlock(block);
+ uiEndBlock(C, block);
uiDrawBlock(block);
}
@@ -416,7 +417,7 @@ static void outliner_main_area_draw(const bContext *C, ARegion *ar)
table= UI_table_create(rows, 2, &rct, rna_table_cell_func, &cell);
RNA_property_collection_begin(&cell.ptr, iterprop, &cell.iter);
- UI_table_draw(C->window, ar, table);
+ UI_table_draw(C, table);
RNA_property_collection_end(&cell.iter);
UI_table_free(table);
@@ -432,7 +433,6 @@ static void outliner_main_area_draw(const bContext *C, ARegion *ar)
static void outliner_main_area_free(ARegion *ar)
{
- uiFreeBlocks(&ar->uiblocks);
}
/* ************************ header outliner area region *********************** */
@@ -466,7 +466,6 @@ static void outliner_header_area_draw(const bContext *C, ARegion *ar)
static void outliner_header_area_free(ARegion *ar)
{
- uiFreeBlocks(&ar->uiblocks);
}
/* ******************** default callbacks for outliner space ***************** */
@@ -506,8 +505,7 @@ static void outliner_init(wmWindowManager *wm, ScrArea *sa)
/* XXX fixme, should be smarter */
- keymap= WM_keymap_listbase(wm, "Interface", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ UI_add_region_handlers(&ar->handlers);
keymap= WM_keymap_listbase(wm, "View2D", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 71446531cbb..51466e22944 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -182,7 +182,6 @@ static void time_header_area_draw(const bContext *C, ARegion *ar)
static void time_header_area_free(ARegion *ar)
{
- uiFreeBlocks(&ar->uiblocks);
}
/* ******************** default callbacks for time space ***************** */
@@ -246,8 +245,7 @@ static void time_init(wmWindowManager *wm, ScrArea *sa)
/* XXX fixme, should be smarter */
- keymap= WM_keymap_listbase(wm, "Interface", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ UI_add_region_handlers(&ar->handlers);
keymap= WM_keymap_listbase(wm, "View2D", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 2cce4d398b9..17b14db2b08 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -109,7 +109,7 @@ typedef struct ScrArea {
struct SpaceType *type; /* callbacks for this space type */
ListBase spacedata;
- ListBase uiblocks;
+ ListBase uiblocks; /* uiBlock */
ListBase panels;
ListBase regionbase; /* ARegion */
ListBase handlers; /* wmEventHandler */
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index dee2f11cb7e..9b720370fcc 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -132,7 +132,7 @@ void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "clone.image");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
- RNA_def_property_ui_text(prop, "Image", "Image for clone tool.");
+ RNA_def_property_ui_text(prop, "Clone Image", "Image for clone tool.");
prop= RNA_def_property(srna, "clone_opacity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clone.alpha");
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 64bfdba081f..a48c2962b7a 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -216,7 +216,7 @@ static void rna_def_image(BlenderRNA *brna)
prop= RNA_def_property(srna, "clamp_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_CLAMP_V);
- RNA_def_property_ui_text(prop, "Clamp y", "Disable texture repeating vertically.");
+ RNA_def_property_ui_text(prop, "Clamp Y", "Disable texture repeating vertically.");
}
void RNA_def_image(BlenderRNA *brna)
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 9dbb4c46947..2f53545f544 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -74,11 +74,13 @@ ListBase *WM_keymap_listbase (wmWindowManager *wm, const char *nameid,
struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap);
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);
+
struct wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op);
-void WM_event_remove_handlers (bContext *C, ListBase *handlers);
+void WM_event_remove_handlers(bContext *C, ListBase *handlers);
-void WM_event_add_message(wmWindowManager *wm, void *customdata,
- short customdatafree);
void WM_event_add_mousemove(bContext *C);
void WM_event_add_notifier(bContext *C, int type, int value, void *data);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index be0fbb4fca6..c8ca8195db0 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -86,8 +86,15 @@ typedef struct wmEvent {
#define KM_RELEASE 0
#define KM_PRESS 1
+/* ************** UI Handler ***************** */
-/* ************** notifiers ****************** */
+#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);
+
+/* ************** Notifiers ****************** */
typedef struct wmNotifier {
struct wmNotifier *prev, *next;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 9d71688fd77..94df7abfed9 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -337,11 +337,35 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
while((handler=handlers->first)) {
BLI_remlink(handlers, handler);
- if(C && handler->op) {
- if(handler->op->type->cancel)
+ if(handler->op) {
+ if(handler->op->type->cancel) {
+ ScrArea *area= C->area;
+ ARegion *region= C->region;
+
+ C->area= handler->op_area;
+ C->region= handler->op_region;
+
handler->op->type->cancel(C, handler->op);
+
+ C->area= area;
+ C->region= region;
+ }
+
wm_operator_free(handler->op);
}
+ else if(handler->ui_remove) {
+ ScrArea *area= C->area;
+ ARegion *region= C->region;
+
+ if(handler->ui_area) C->area= handler->ui_area;
+ if(handler->ui_region) C->region= handler->ui_region;
+
+ handler->ui_remove(C);
+
+ C->area= area;
+ C->region= region;
+ }
+
wm_event_free_handler(handler);
MEM_freeN(handler);
}
@@ -428,10 +452,32 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
return WM_HANDLER_BREAK;
}
+static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *event)
+{
+ ScrArea *area= C->area;
+ ARegion *region= C->region;
+ int retval;
+
+ /* we set context to where ui handler came from */
+ if(handler->ui_area) C->area= handler->ui_area;
+ if(handler->ui_region) C->region= handler->ui_region;
+
+ retval= handler->ui_handle(C, event);
+
+ /* putting back screen context */
+ C->area= area;
+ C->region= region;
+
+ if(retval == WM_UI_HANDLER_BREAK)
+ return WM_HANDLER_BREAK;
+
+ return WM_HANDLER_CONTINUE;
+}
+
static int wm_event_always_pass(wmEvent *event)
{
/* some events we always pass on, to ensure proper communication */
- return (event->type == TIMER || event->type == MESSAGE);
+ return (event->type == TIMER);
}
static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
@@ -465,6 +511,9 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
}
}
}
+ else if(handler->ui_handle) {
+ action= wm_handler_ui_call(C, handler, event);
+ }
else {
/* modal, swallows all */
action= wm_handler_operator_call(C, handlers, handler, event);
@@ -543,26 +592,6 @@ void wm_event_do_handlers(bContext *C)
action= wm_handlers_do(C, event, &win->handlers);
- /* modal menus in Blender use (own) regions linked to screen */
- if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
- ARegion *ar;
-
- /* region are in drawing order, i.e. frontmost region last so
- * we handle events in the opposite order last to first */
- for(ar=win->screen->regionbase.last; ar; ar= ar->prev) {
- if(wm_event_always_pass(event) || wm_event_inside_i(event, &ar->winrct)) {
- C->region= ar;
- wm_handlers_do(C, event, &ar->handlers);
- C->region= NULL;
-
- if(!wm_event_always_pass(event)) {
- action= WM_HANDLER_BREAK;
- break;
- }
- }
- }
- }
-
if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
ScrArea *sa;
ARegion *ar;
@@ -576,7 +605,7 @@ void wm_event_do_handlers(bContext *C)
if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
for(ar=sa->regionbase.first; ar; ar= ar->next) {
- if(wm_event_always_pass(event) || wm_event_inside_i(event, &ar->winrct)) {
+ if(wm_event_always_pass(event) || wm_event_inside_i(event, &ar->winrct) || wm_event_prev_inside_i(event, &ar->winrct)) {
C->region= ar;
action= wm_handlers_do(C, event, &ar->handlers);
C->region= NULL;
@@ -616,13 +645,13 @@ void WM_event_set_handler_flag(wmEventHandler *handler, int flag)
wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op)
{
- wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
+ wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event modal handler");
handler->op= op;
handler->op_area= C->area; /* means frozen screen context for modal handlers! */
handler->op_region= C->region;
BLI_addhead(handlers, handler);
-
+
return handler;
}
@@ -635,7 +664,7 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap
if(handler->keymap==keymap)
return handler;
- handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
+ handler= MEM_callocN(sizeof(wmEventHandler), "event keymap handler");
BLI_addtail(handlers, handler);
handler->keymap= keymap;
@@ -656,21 +685,30 @@ void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap)
}
}
-void WM_event_add_message(wmWindowManager *wm, void *customdata, short customdatafree)
+wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove)
{
- wmEvent event;
- wmWindow *win;
-
- for(win=wm->windows.first; win; win=win->next) {
- event= *(win->eventstate);
+ wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event ui handler");
+ handler->ui_handle= func;
+ handler->ui_remove= remove;
+ handler->ui_area= (C)? C->area: NULL;
+ handler->ui_region= (C)? C->region: NULL;
+
+ BLI_addhead(handlers, handler);
+
+ return handler;
+}
- event.type= MESSAGE;
- if(customdata) {
- event.custom= EVT_DATA_MESSAGE;
- event.customdata= customdata;
- event.customdatafree= customdatafree;
+void WM_event_remove_ui_handler(ListBase *handlers)
+{
+ wmEventHandler *handler;
+
+ for(handler= handlers->first; handler; handler= handler->next) {
+ if(handler->ui_handle) {
+ BLI_remlink(handlers, handler);
+ wm_event_free_handler(handler);
+ MEM_freeN(handler);
+ break;
}
- wm_event_add(win, &event);
}
}
@@ -678,8 +716,9 @@ void WM_event_add_mousemove(bContext *C)
{
wmEvent event= *(C->window->eventstate);
event.type= MOUSEMOVE;
+ event.prevx= event.x;
+ event.prevy= event.y;
wm_event_add(C->window, &event);
-
}
/* ********************* ghost stuff *************** */
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 0c37c56778f..61670388879 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -40,15 +40,21 @@ struct ARegion;
typedef struct wmEventHandler {
struct wmEventHandler *next, *prev;
- int type, flag; /* type default=0, rest is custom */
+ int type, flag; /* type default=0, rest is custom */
- ListBase *keymap; /* pointer to builtin/custom keymaps */
+ /* keymap handler */
+ ListBase *keymap; /* pointer to builtin/custom keymaps */
- rctf boundbox; /* float, in bContext space (window, area, region) */
-
- wmOperator *op; /* for derived/modal handlers */
+ /* modal operator handler */
+ wmOperator *op; /* for derived/modal handlers */
struct ScrArea *op_area; /* for derived/modal handlers */
struct ARegion *op_region; /* for derived/modal handlers */
+
+ /* ui handler */
+ wmUIHandlerFunc ui_handle; /* callback receiving events */
+ wmUIHandlerRemoveFunc ui_remove; /* callback when handler is removed */
+ struct ScrArea *ui_area; /* for derived/modal handlers */
+ struct ARegion *ui_region; /* for derived/modal handlers */
} wmEventHandler;
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 265132eacf9..87c9e3cb2db 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -39,7 +39,6 @@
#define EVT_DATA_TABLET 1
#define EVT_DATA_GESTURE 2
#define EVT_DATA_TIMER 3
-#define EVT_DATA_MESSAGE 4
#define MOUSEX 0x004
#define MOUSEY 0x005
@@ -69,7 +68,6 @@
#define WINQUIT 0x0108 /* signal from user that app is to go away */
#define Q_FIRSTTIME 0x0109 /* on startup */
#define TIMER 0x0110 /* timer event */
-#define MESSAGE 0x0111 /* message event */
/* standard keyboard */