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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-11 23:30:41 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-11 23:30:41 +0300
commita10752f4bcf005fba1f8bbd37bf0c68499246e5a (patch)
tree74b03788ec931236e684f00f7baa5aecaf23c7bd /source/blender/editors
parent7a1100c8b536a63a72f3a28947f31c9cf94480d5 (diff)
UI: restored mechanism to only call button/block callback functions
after the menus are closed, to avoid conflicts with those callbacks manipulating their own area or region.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/interface/interface.c3
-rw-r--r--source/blender/editors/interface/interface.h3
-rw-r--r--source/blender/editors/interface/interface_handlers.c79
3 files changed, 70 insertions, 15 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index a9ea563bb6a..2562a5e6bb3 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1948,9 +1948,6 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
but->func_arg2= block->func_arg2;
}
- but->handle_func= block->handle_func;
- but->handle_func_arg= block->handle_func_arg;
-
ui_set_embossfunc(but, block->dt);
but->pos= -1; /* cursor invisible */
diff --git a/source/blender/editors/interface/interface.h b/source/blender/editors/interface/interface.h
index 9b2ce5680b3..330639cce93 100644
--- a/source/blender/editors/interface/interface.h
+++ b/source/blender/editors/interface/interface.h
@@ -129,9 +129,6 @@ struct uiBut {
void *func_arg1;
void *func_arg2;
- void (*handle_func)(struct bContext*, void *arg, int event);
- void *handle_func_arg;
-
void (*embossfunc)(int , int , float, float, float, float, float, int);
void (*sliderfunc)(int , float, float, float, float, float, float, int);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index f2be0230969..a81b80c5abe 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -134,26 +134,75 @@ typedef struct uiHandleButtonData {
uiBut *postbut;
} uiHandleButtonData;
+typedef struct uiAfterFunc {
+ struct uiAfterFunc *next, *prev;
+
+ void (*func)(struct bContext*, void *, void *);
+ void *func_arg1;
+ void *func_arg2;
+
+ void (*handle_func)(struct bContext*, void *arg, int event);
+ void *handle_func_arg;
+ int retval;
+
+ void (*butm_func)(struct bContext*, void *arg, int event);
+ void *butm_func_arg;
+ int a2;
+} uiAfterFunc;
+
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
static int ui_handler_window(bContext *C, wmEvent *event);
-/* ********************** button apply/revert ************************ */
+/* ********************** button apply/revert ************************/
+
+static ListBase UIAfterFuncs = {NULL, NULL};
static void ui_apply_but_func(bContext *C, uiBut *but)
{
+ uiAfterFunc *after;
uiBlock *block= but->block;
- if(but->func)
- but->func(C, but->func_arg1, but->func_arg2);
-
- if(block) {
- if(block->handle_func)
- block->handle_func(C, block->handle_func_arg, but->retval);
- if(but->type == BUTM && block->butm_func)
- block->butm_func(C, block->butm_func_arg, but->a2);
+ /* these functions are postponed and only executed after all other
+ * handling is done, i.e. menus are closed, in order to avoid conflicts
+ * with these functions removing the buttons we are working with */
+
+ if(but->func || block->handle_func || (but->type == BUTM && block->butm_func)) {
+ after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
+ after->func= but->func;
+ after->func_arg1= but->func_arg1;
+ after->func_arg2= but->func_arg2;
+
+ after->handle_func= block->handle_func;
+ after->handle_func_arg= block->handle_func_arg;
+ after->retval= but->retval;
+
+ if(but->type == BUTM) {
+ after->butm_func= block->butm_func;
+ after->butm_func_arg= block->butm_func_arg;
+ after->a2= but->a2;
+ }
+
+ BLI_addtail(&UIAfterFuncs, after);
}
}
+static void ui_apply_but_funcs_after(bContext *C)
+{
+ uiAfterFunc *after;
+
+ for(after=UIAfterFuncs.first; after; after=after->next) {
+ if(after->func)
+ after->func(C, after->func_arg1, after->func_arg2);
+
+ if(after->handle_func)
+ after->handle_func(C, after->handle_func_arg, after->retval);
+ if(after->butm_func)
+ after->butm_func(C, after->butm_func_arg, after->a2);
+ }
+
+ BLI_freelistN(&UIAfterFuncs);
+}
+
static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data)
{
ui_apply_but_func(C, but);
@@ -3472,6 +3521,9 @@ static int ui_handler_region(bContext *C, wmEvent *event)
/* re-enable tooltips */
if(event->type == MOUSEMOVE && (event->x!=event->prevx || event->y!=event->prevy))
ui_blocks_set_tooltips(ar, 1);
+
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
return retval;
}
@@ -3484,6 +3536,12 @@ static void ui_handler_remove_region(bContext *C)
if(ar==NULL) return;
uiFreeBlocks(C, &ar->uiblocks);
+
+ /* delayed apply callbacks, but not for screen level regions, those
+ * we rather do at the very end after closing them all, which will
+ * be done in ui_handler_region/window */
+ if(BLI_findindex(&C->screen->regionbase, ar) == -1)
+ ui_apply_but_funcs_after(C);
}
static int ui_handler_window(bContext *C, wmEvent *event)
@@ -3526,6 +3584,9 @@ static int ui_handler_window(bContext *C, wmEvent *event)
if(event->type == MOUSEMOVE && (event->x!=event->prevx || event->y!=event->prevy))
ui_blocks_set_tooltips(ar, 1);
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
+
/* we block all events, this is modal interaction */
return WM_UI_HANDLER_BREAK;
}