diff options
author | Matt Ebb <matt@mke3.net> | 2010-06-03 11:27:55 +0400 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2010-06-03 11:27:55 +0400 |
commit | 21d112c36f661f3ce8648f4eadfe1325929e9184 (patch) | |
tree | 0f880b11d750b7d5800154faa67e9920012e8b83 | |
parent | 3b6aa5b6a588b76e1ed6f25f11ae77dd07ecfa46 (diff) |
Reworked the non-blocking reports display in the info header:
* Now it displays the last report from the global list, not just from operators
* Rather than disappearing when a new operator is run, it stays until it times
out or a new report is added
* Fun animated transitions ;)
http://mke3.net/blender/devel/2.5/reports_header.mov
Now need to investigate report usage with popups. Ideally we can have most
reports non-blocking, so they're less intrusive, only popping up for dire errors.
Problem is many things in Blender right now are marked as RPT_ERROR
when probably RPT_WARNING is more appropriate. Should probably keep
RPT_ERROR for things that demand immediate attention.
-rw-r--r-- | release/scripts/ui/space_info.py | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_report.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/report.c | 12 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 83 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 14 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 14 | ||||
-rw-r--r-- | source/blender/editors/space_info/info_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_info/info_ops.c | 98 | ||||
-rw-r--r-- | source/blender/editors/space_info/space_info.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_windowmanager_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui_api.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 16 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 87 |
14 files changed, 261 insertions, 93 deletions
diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 62db983b87e..7d28b5a883c 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -65,10 +65,9 @@ class INFO_HT_header(bpy.types.Header): layout.template_running_jobs() - if last_op and last_op.has_reports: - layout.template_reports_banner(last_op) - else: - layout.label(text=scene.statistics()) + layout.template_reports_banner() + + layout.label(text=scene.statistics()) # XXX: this should be right-aligned to the RHS of the region layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER', text="") diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h index 62381bbc1f5..d7b7801d697 100644 --- a/source/blender/blenkernel/BKE_report.h +++ b/source/blender/blenkernel/BKE_report.h @@ -59,6 +59,8 @@ void BKE_report_store_level_set(ReportList *reports, ReportType level); char *BKE_reports_string(ReportList *reports, ReportType level); void BKE_reports_print(ReportList *reports, ReportType level); +Report *BKE_reports_last_displayable(ReportList *reports); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index da8b018d3f8..d5990ce81ec 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -32,6 +32,7 @@ #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ +#include "BKE_utildefines.h" #include <stdarg.h> #include <stdio.h> @@ -262,3 +263,14 @@ void BKE_reports_print(ReportList *reports, ReportType level) MEM_freeN(cstring); } +Report *BKE_reports_last_displayable(ReportList *reports) +{ + Report *report=NULL; + + for (report= (Report *)reports->list.last; report; report=report->prev) { + if (ELEM3(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO)) + return report; + } + + return NULL; +}
\ No newline at end of file diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index c62963c5b3b..db479b45472 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -693,7 +693,7 @@ void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C); void uiTemplateOperatorSearch(uiLayout *layout); void uiTemplateHeader3D(uiLayout *layout, struct bContext *C); void uiTemplateTextureImage(uiLayout *layout, struct bContext *C, struct Tex *tex); -void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C, struct wmOperator *op); +void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C); void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int maxrows, int type); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 4183ff49e51..05c162ef639 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -30,6 +30,7 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +#include "DNA_windowmanager_types.h" #include "BLI_string.h" @@ -53,6 +54,8 @@ #include "UI_interface.h" #include "interface_intern.h" +#include "BLF_api.h" + void ui_template_fix_linking() { } @@ -2455,49 +2458,59 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast"); if(screen->animtimer) uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, "Anim Player", 0,0,100,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); - - uiItemS(layout); } /************************* Reports for Last Operator Template **************************/ -void uiTemplateReportsBanner(uiLayout *layout, bContext *C, wmOperator *op) +void uiTemplateReportsBanner(uiLayout *layout, bContext *C) { - ReportList *reports = op->reports; - uiLayout *box; + ReportList *reports = CTX_wm_reports(C); + Report *report= BKE_reports_last_displayable(reports); + ReportTimerInfo *rti; - /* sanity checks */ - if (ELEM(NULL, op, reports)) { - printf("uiTemplateReportsBanner: no operator with reports!\n"); - return; - } + uiLayout *abs; + uiBlock *block; + uiBut *but; + uiStyle *style= U.uistyles.first; + int width; + float hsv[3]; + + /* if the report display has timed out, don't show */ + if (!reports->reporttimer) return; + + rti= (ReportTimerInfo *)reports->reporttimer->customdata; + + if (!rti || rti->widthfac==0.0 || !report) return; + + abs = uiLayoutAbsolute(layout, 0); + block= uiLayoutGetBlock(abs); + + rgb_to_hsv(rti->col[0], rti->col[1], rti->col[2], hsv+0, hsv+1, hsv+2); + + width = BLF_width(style->widget.uifont_id, report->message); + width = MIN2(rti->widthfac*width, width); + width = MAX2(width, 10); /* make a box around the report to make it stand out */ - box = uiLayoutBox(layout); - uiLayoutSetScaleY(box, 0.48); /* experimentally determined value to reduce execessive padding... */ + uiBlockBeginAlign(block); + but= uiDefBut(block, ROUNDBOX, 0, "", 0, 0, UI_UNIT_X+10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + copy_v3_v3(but->hsv, hsv); /* set the report's bg colour in but->hsv - ROUNDBOX feature */ - /* if more than one report, we need to show the popup when user clicks on the temp label... */ - if (reports->list.first != reports->list.last) { - int numReports = BLI_countlist(&reports->list); - char buf[64]; - - // XXX: we need uiItem* to return uiBut pointer so that we can use it to set callbacks - // used to call uiPupMenuReports... as alternative, we could fall back to the "old ways" - //sprintf(buf, "Last Operator had %d errors. Click to see more...", numReports); - sprintf(buf, "Last Operator had %d errors", numReports); - uiItemL(box, buf, ICON_INFO); - } - else { - /* single report, so show report directly */ - // XXX: what if the report is too long? should we truncate the text? - Report *report= (Report *)reports->list.first; - - if(report->type >= RPT_ERROR) - uiItemL(box, report->message, ICON_ERROR); - else if(report->type >= RPT_WARNING) - uiItemL(box, report->message, ICON_ERROR); - else if(report->type >= RPT_INFO) - uiItemL(box, report->message, ICON_INFO); - } + but= uiDefBut(block, ROUNDBOX, 0, "", UI_UNIT_X+10, 0, UI_UNIT_X+width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + but->hsv[0] = but->hsv[1] = 0.0; /* set a greyscale bg colour in but->hsv - ROUNDBOX feature */ + but->hsv[2] = rti->greyscale; + uiBlockEndAlign(block); + + + /* icon and report message on top */ + if(report->type & RPT_ERROR_ALL) + uiDefIconBut(block, LABEL, 0, ICON_ERROR, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + else if(report->type & RPT_WARNING_ALL) + uiDefIconBut(block, LABEL, 0, ICON_ERROR, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + else if(report->type & RPT_INFO_ALL) + uiDefIconBut(block, LABEL, 0, ICON_INFO, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + + uiDefBut(block, LABEL, 0, report->message, UI_UNIT_X+10, 0, UI_UNIT_X+width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c419c73c1e0..dfca12b1d49 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2368,9 +2368,21 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int state, int rou static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; + char old_col[3]; widget_init(&wtb); + VECCOPY(old_col, wcol->inner); + + /* abuse but->hsv - if it's non-zero, use this colour as the box's background */ + if ((but->hsv[0] != 0.0) || (but->hsv[1] != 0.0) || (but->hsv[2] != 0.0)) { + float rgb[3]; + hsv_to_rgb(but->hsv[0], but->hsv[1], but->hsv[2], rgb+0, rgb+1, rgb+2); + wcol->inner[0] = rgb[0] * 255; + wcol->inner[1] = rgb[1] * 255; + wcol->inner[2] = rgb[2] * 255; + } + /* half rounded */ round_box_edges(&wtb, roundboxalign, rect, 4.0f); @@ -2379,6 +2391,8 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, /* store the box bg as gl clearcolor, to retrieve later when drawing semi-transparent rects * over the top to indicate disabled buttons */ glClearColor(wcol->inner[0]/255.0, wcol->inner[1]/255.0, wcol->inner[2]/255.0, 1.0); + + VECCOPY(wcol->inner, old_col); } static void widget_but(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 8cd8688d448..64c4a76ae9d 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -481,15 +481,11 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - /*char msg[100];*/ - - /*int cnt =*/ removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); - /*XXX this messes up last operator panel - if(cnt) - { - sprintf(msg, "Removed %d vertices", cnt); - BKE_report(op->reports, RPT_INFO, msg); - }*/ + + int count = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); + + if(count) + BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", cnt); DAG_id_flush_update(obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h index 128c0dace20..4053bbf5a1f 100644 --- a/source/blender/editors/space_info/info_intern.h +++ b/source/blender/editors/space_info/info_intern.h @@ -39,5 +39,7 @@ void FILE_OT_make_paths_absolute(struct wmOperatorType *ot); void FILE_OT_report_missing_files(struct wmOperatorType *ot); void FILE_OT_find_missing_files(struct wmOperatorType *ot); +void INFO_OT_reports_display_update(struct wmOperatorType *ot); + #endif /* ED_INFO_INTERN_H */ diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index e2baeb9abac..64d2c6138c7 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_math.h" #include "BLI_bpath.h" #include "BKE_context.h" @@ -300,3 +301,100 @@ void FILE_OT_find_missing_files(wmOperatorType *ot) /* properties */ WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE); } + +/********************* report box operator *********************/ + +/* Hard to decide whether to keep this as an operator, + * or turn it into a hardcoded ui control feature, + * handling TIMER events for all regions in interface_handlers.c + * Not sure how good that is to be accessing UI data from + * inactive regions, so use this for now. --matt + */ + +#define INFO_TIMEOUT 5.0 +#define INFO_COLOR_TIMEOUT 3.0 +#define ERROR_TIMEOUT 10.0 +#define ERROR_COLOR_TIMEOUT 6.0 +#define COLLAPSE_TIMEOUT 0.2 +static int update_reports_display_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + wmWindowManager *wm= CTX_wm_manager(C); + ReportList *reports= CTX_wm_reports(C); + Report *report; + ReportTimerInfo *rti; + float progress=0.0, color_progress=0.0; + float neutral_col[3] = {0.35, 0.35, 0.35}; + float neutral_grey= 0.6; + float timeout=0.0, color_timeout=0.0; + + /* escape if not our timer */ + if(reports->reporttimer==NULL || reports->reporttimer != event->customdata) + return OPERATOR_PASS_THROUGH; + + report= BKE_reports_last_displayable(reports); + rti = (ReportTimerInfo *)reports->reporttimer->customdata; + + timeout = (report->type & RPT_ERROR_ALL)?ERROR_TIMEOUT:INFO_TIMEOUT; + color_timeout = (report->type & RPT_ERROR_ALL)?ERROR_COLOR_TIMEOUT:INFO_COLOR_TIMEOUT; + + /* clear the report display after timeout */ + if (reports->reporttimer->duration > timeout) { + WM_event_remove_timer(wm, NULL, reports->reporttimer); + reports->reporttimer = NULL; + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO, NULL); + + return (OPERATOR_FINISHED|OPERATOR_PASS_THROUGH); + } + + if (rti->widthfac == 0.0) { + /* initialise colours based on report type */ + if(report->type & RPT_ERROR_ALL) { + rti->col[0] = 1.0; + rti->col[1] = 0.2; + rti->col[2] = 0.0; + } else if(report->type & RPT_WARNING_ALL) { + rti->col[0] = 1.0; + rti->col[1] = 1.0; + rti->col[2] = 0.0; + } else if(report->type & RPT_INFO_ALL) { + rti->col[0] = 0.3; + rti->col[1] = 0.45; + rti->col[2] = 0.7; + } + rti->greyscale = 0.75; + rti->widthfac=1.0; + } + + progress = reports->reporttimer->duration / timeout; + color_progress = reports->reporttimer->duration / color_timeout; + + /* fade colours out sharply according to progress through fade-out duration */ + interp_v3_v3v3(rti->col, rti->col, neutral_col, color_progress); + rti->greyscale = interpf(neutral_grey, rti->greyscale, color_progress); + + /* collapse report at end of timeout */ + if (progress*timeout > timeout - COLLAPSE_TIMEOUT) { + rti->widthfac = (progress*timeout - (timeout - COLLAPSE_TIMEOUT)) / COLLAPSE_TIMEOUT; + rti->widthfac = 1.0 - rti->widthfac; + } + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO, NULL); + + return (OPERATOR_FINISHED|OPERATOR_PASS_THROUGH); +} + +void INFO_OT_reports_display_update(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Update Reports Display"; + ot->idname= "INFO_OT_reports_display_update"; + + /* api callbacks */ + ot->invoke= update_reports_display_invoke; + + /* flags */ + ot->flag= 0; + + /* properties */ +}
\ No newline at end of file diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 4370d2cbc16..0d9f1c90489 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -125,11 +125,15 @@ void info_operatortypes(void) WM_operatortype_append(FILE_OT_make_paths_absolute); WM_operatortype_append(FILE_OT_report_missing_files); WM_operatortype_append(FILE_OT_find_missing_files); + + WM_operatortype_append(INFO_OT_reports_display_update); } void info_keymap(struct wmKeyConfig *keyconf) { + wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0); + WM_keymap_verify_item(keymap, "INFO_OT_reports_display_update", TIMER, KM_ANY, KM_ANY, 0); } /* add handlers, stuff you only do once or on area/region changes */ diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index e1c3dcf82c4..ed52316990e 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -96,7 +96,16 @@ typedef struct ReportList { int printlevel; /* ReportType */ int storelevel; /* ReportType */ int flag, pad; + struct wmTimer *reporttimer; } ReportList; + +/* timer customdata to control reports display */ +typedef struct ReportTimerInfo { + float col[3]; + float greyscale; + float widthfac; +} ReportTimerInfo; + /* reports need to be before wmWindowManager */ diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 7c78d8a74e7..ccea5fbdf93 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -398,10 +398,6 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "template_reports_banner", "uiTemplateReportsBanner"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); - parm= RNA_def_pointer(func, "operator", "Operator", "", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "introspect", "uiLayoutIntrospect"); parm= RNA_def_string(func, "string", "", 1024*1024, "Descr", "DESCR"); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 452c37dbe77..fcf8951d796 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -98,13 +98,18 @@ void WM_operator_free(wmOperator *op) MEM_freeN(op); } +static void wm_reports_free(wmWindowManager *wm) +{ + BKE_reports_clear(&wm->reports); + WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); +} + /* all operations get registered in the windowmanager here */ /* called on event handling by event_system.c */ void wm_operator_register(bContext *C, wmOperator *op) { wmWindowManager *wm= CTX_wm_manager(C); int tot; - char *buf; BLI_addtail(&wm->operators, op); tot= BLI_countlist(&wm->operators); @@ -116,12 +121,6 @@ void wm_operator_register(bContext *C, wmOperator *op) tot--; } - - /* Report the string representation of the operator */ - buf = WM_operator_pystring(C, op->type, op->ptr, 1); - BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf); - MEM_freeN(buf); - /* so the console is redrawn */ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); WM_event_add_notifier(C, NC_WM|ND_HISTORY, NULL); @@ -309,7 +308,8 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) BLI_freelistN(&wm->paintcursors); BLI_freelistN(&wm->drags); - BKE_reports_clear(&wm->reports); + + wm_reports_free(wm); if(C && CTX_wm_manager(C)==wm) CTX_wm_manager_set(C, NULL); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 84a6b3598d7..b55c68ce029 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -372,15 +372,56 @@ int WM_operator_poll(bContext *C, wmOperatorType *ot) return 1; } +static void wm_operator_print(wmOperator *op) +{ + char *buf = WM_operator_pystring(NULL, op->type, op->ptr, 1); + printf("%s\n", buf); + MEM_freeN(buf); +} + +static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int popup) +{ + wmWindowManager *wm = CTX_wm_manager(C); + ReportList *reports = CTX_wm_reports(C); + char *buf; + + if(popup) + if(op->reports->list.first) + uiPupMenuReports(C, op->reports); + + if(retval & OPERATOR_FINISHED) { + if(G.f & G_DEBUG) + wm_operator_print(op); /* todo - this print may double up, might want to check more flags then the FINISHED */ + + /* Report the python string representation of the operator */ + buf = WM_operator_pystring(C, op->type, op->ptr, 1); + BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf); + MEM_freeN(buf); + } + + if (op->reports->list.first) { + ReportTimerInfo *rti; + + /* add reports to the global list, otherwise they are not seen */ + addlisttolist(&CTX_wm_reports(C)->list, &op->reports->list); + + /* After adding reports to the global list, reset the report timer. */ + WM_event_remove_timer(wm, NULL, reports->reporttimer); + + /* Records time since last report was added */ + reports->reporttimer= WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02); + + rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo"); + reports->reporttimer->customdata = rti; + } +} + static void wm_operator_finished(bContext *C, wmOperator *op, int repeat) { wmWindowManager *wm= CTX_wm_manager(C); op->customdata= NULL; - /* add reports to the global list, otherwise they are not seen */ - addlisttolist(&CTX_wm_reports(C)->list, &op->reports->list); - /* we don't want to do undo pushes for operators that are being called from operators that already do an undo push. usually this will happen for python operators that call C operators */ @@ -424,9 +465,8 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat) wm->op_undo_depth--; } - if(retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) - if(op->reports->list.first) - uiPupMenuReports(C, op->reports); + if (retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED) && repeat == 0) + wm_operator_reports(C, op, retval, 0); if(retval & OPERATOR_FINISHED) wm_operator_finished(C, op, repeat); @@ -534,13 +574,6 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P return op; } -static void wm_operator_print(wmOperator *op) -{ - char *buf = WM_operator_pystring(NULL, op->type, op->ptr, 1); - printf("%s\n", buf); - MEM_freeN(buf); -} - static void wm_region_mouse_co(bContext *C, wmEvent *event) { ARegion *ar= CTX_wm_region(C); @@ -584,18 +617,14 @@ int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerR } else printf("invalid operator call %s\n", ot->idname); /* debug, important to leave a while, should never happen */ - + /* Note, if the report is given as an argument then assume the caller will deal with displaying them * currently python only uses this */ - if((retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) && reports==NULL) - if(op->reports->list.first) /* only show the report if the report list was not given in the function */ - uiPupMenuReports(C, op->reports); + if (!(retval & OPERATOR_HANDLED) && retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) + /* only show the report if the report list was not given in the function */ + wm_operator_reports(C, op, retval, (reports==NULL)); + - if (retval & OPERATOR_FINISHED) { /* todo - this may conflict with the other wm_operator_print, if theres ever 2 prints for 1 action will may need to add modal check here */ - if(G.f & G_DEBUG) - wm_operator_print(op); - } - if(retval & OPERATOR_HANDLED) ; /* do nothing, wm_operator_exec() has been called somewhere */ else if(retval & OPERATOR_FINISHED) { @@ -1084,17 +1113,11 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand /* this special cases is for areas and regions that get removed */ CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); - } - - if(retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) - if(op->reports->list.first) - uiPupMenuReports(C, op->reports); - - if (retval & OPERATOR_FINISHED) { - if(G.f & G_DEBUG) - wm_operator_print(op); /* todo - this print may double up, might want to check more flags then the FINISHED */ - } + } + if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) + wm_operator_reports(C, op, retval, 0); + if(retval & OPERATOR_FINISHED) { wm_operator_finished(C, op, 0); handler->op= NULL; |