diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2016-01-18 03:39:09 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2016-01-18 03:39:09 +0300 |
commit | c6bc2363e5ec96d1aba36f1e7b4d321076d3f465 (patch) | |
tree | a09fa844a679328a72c3dc3e00d8a1a9bf26a6cd | |
parent | c4c2bd1350a52e18f973bba7e52e929f94ff6496 (diff) |
UI: redesign of the progress bar.
A picture is worth a thousand words: http://wiki.blender.org/index.php/
File:UI_progress_bar.png
Reviewers: #user_interface, brecht, dingto
Reviewed by: brecht, dingto
Differential Revision: https://developer.blender.org/D1727
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 84 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 45 | ||||
-rw-r--r-- | source/blender/editors/interface/resources.c | 9 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_jobs.c | 46 |
6 files changed, 156 insertions, 34 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 18edfdacd79..97d1a89afdb 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 276 -#define BLENDER_SUBVERSION 7 +#define BLENDER_SUBVERSION 8 /* Several breakages with 270, e.g. constraint deg vs rad */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 6 diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ccb0c9f508d..a97f55d4749 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -45,6 +45,7 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_fnmatch.h" +#include "BLI_timecode.h" #include "BLF_api.h" #include "BLT_translation.h" @@ -81,6 +82,8 @@ #include "UI_interface_icons.h" #include "interface_intern.h" +#include "PIL_time.h" + void UI_template_fix_linking(void) { } @@ -3383,7 +3386,7 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) ScrArea *sa = CTX_wm_area(C); uiBlock *block; void *owner = NULL; - int handle_event; + int handle_event, icon = 0; block = uiLayoutGetBlock(layout); UI_block_layout_set_current(block, layout); @@ -3394,17 +3397,20 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY)) owner = sa; handle_event = B_STOPSEQ; + icon = ICON_SEQUENCE; } else if (sa->spacetype == SPACE_CLIP) { if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY)) owner = sa; handle_event = B_STOPCLIP; + icon = ICON_CLIP; } else if (sa->spacetype == SPACE_FILE) { if (WM_jobs_test(wm, sa, WM_JOB_TYPE_FILESEL_READDIR)) { owner = sa; } handle_event = B_STOPFILE; + icon = ICON_FILESEL; } else { Scene *scene; @@ -3412,10 +3418,12 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) for (scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next) { if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) { handle_event = B_STOPRENDER; + icon = ICON_SCENE; break; } else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_COMPOSITE)) { handle_event = B_STOPCOMPO; + icon = ICON_RENDERLAYERS; break; } else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE) || @@ -3427,11 +3435,33 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) */ if (sa->spacetype != SPACE_NODE) { handle_event = B_STOPOTHER; + icon = ICON_IMAGE_COL; break; } } + else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_DPAINT_BAKE)) { + handle_event = B_STOPOTHER; + icon = ICON_MOD_DYNAMICPAINT; + break; + } + else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_POINTCACHE)) { + handle_event = B_STOPOTHER; + icon = ICON_PHYSICS; + break; + } + else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_FLUID)) { + handle_event = B_STOPOTHER; + icon = ICON_MOD_FLUIDSIM; + break; + } + else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_OCEAN)) { + handle_event = B_STOPOTHER; + icon = ICON_MOD_OCEAN; + break; + } else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) { handle_event = B_STOPOTHER; + icon = ICON_NONE; break; } } @@ -3439,18 +3469,52 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) } if (owner) { - uiLayout *ui_abs; - - ui_abs = uiLayoutAbsolute(layout, false); - (void)ui_abs; /* UNUSED */ + const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; + bool active = !(WM_jobs_is_stopped(wm, owner) || G.is_break); - uiDefIconBut(block, UI_BTYPE_BUT, handle_event, ICON_PANEL_CLOSE, 0, UI_UNIT_Y * 0.1, UI_UNIT_X * 0.8, UI_UNIT_Y * 0.8, - NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop this job")); - uiDefBut(block, UI_BTYPE_PROGRESS_BAR, 0, WM_jobs_name(wm, owner), - UI_UNIT_X, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y, NULL, 0.0f, 0.0f, WM_jobs_progress(wm, owner), 0, TIP_("Progress")); + uiLayout *row = uiLayoutRow(layout, false); + block = uiLayoutGetBlock(row); + + /* get percentage done and set it as the UI text */ + const float progress = WM_jobs_progress(wm, owner); + char text[8]; + BLI_snprintf(text, 8, "%d%%", (int)(progress * 100)); - uiLayoutRow(layout, false); + /* create tooltip text and associate it with the job */ + + const double elapsed = PIL_check_seconds_timer() - WM_jobs_starttime(wm, owner); + const double remaining = (elapsed / progress) - elapsed; + + char remaining_str[32], elapsed_str[32]; + BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining); + BLI_timecode_string_from_time_simple(elapsed_str, sizeof(remaining_str), elapsed); + + char tooltip[128]; + BLI_snprintf(tooltip, sizeof(tooltip), "Time Remaining: %s\nTime Elapsed: %s", remaining_str, elapsed_str); + + WM_jobs_set_tooltip(wm, owner, tooltip); + + const char *name = active ? WM_jobs_name(wm, owner) : "Canceling..."; + + /* job name and icon */ + const int textwidth = UI_fontstyle_string_width(fstyle, name); + uiDefIconTextBut(block, UI_BTYPE_LABEL, 0, icon, name, 0, 0, + textwidth + UI_UNIT_X * 1.5f, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0.0f, 0.0f, ""); + + /* stick progress bar and cancel button together */ + row = uiLayoutRow(layout, true); + uiLayoutSetActive(row, active); + block = uiLayoutGetBlock(row); + + uiDefIconTextBut(block, UI_BTYPE_PROGRESS_BAR, 0, 0, text, + UI_UNIT_X, 0, UI_UNIT_X * 6.0f, UI_UNIT_Y, NULL, 0.0f, 0.0f, + progress, 0, WM_jobs_tooltip(wm, owner)); + + uiDefIconTextBut(block, UI_BTYPE_BUT, handle_event, ICON_PANEL_CLOSE, + "", 0, 0, UI_UNIT_X, UI_UNIT_Y, + NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop this job")); } + if (WM_jobs_test(wm, screen, WM_JOB_TYPE_SCREENCAST)) uiDefIconTextBut(block, UI_BTYPE_BUT, B_STOPCAST, ICON_CANCEL, IFACE_("Capture"), 0, 0, UI_UNIT_X * 4.25f, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop screencast")); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 8198f68adf1..e493fe96f9c 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1854,7 +1854,7 @@ static struct uiWidgetColors wcol_progress = { {0, 0, 0, 255}, {190, 190, 190, 255}, {100, 100, 100, 180}, - {68, 68, 68, 255}, + {128, 128, 128, 255}, {0, 0, 0, 255}, {255, 255, 255, 255}, @@ -2863,30 +2863,37 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat UI_draw_widget_scroll(wcol, rect, &rect1, state); } -static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) +static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { + uiWidgetBase wtb, wtb_bar; rcti rect_prog = *rect, rect_bar = *rect; + + widget_init(&wtb); + widget_init(&wtb_bar); + + /* round corners */ float value = but->a1; - float w, min; - - /* make the progress bar a proportion of the original height */ - /* hardcoded 4px high for now */ - rect_prog.ymax = rect_prog.ymin + 4 * UI_DPI_FAC; - rect_bar.ymax = rect_bar.ymin + 4 * UI_DPI_FAC; - - w = value * BLI_rcti_size_x(&rect_prog); - + float offs = 0.25f * BLI_rcti_size_y(&rect_prog); + float w = value * BLI_rcti_size_x(&rect_prog); + /* ensure minimium size */ - min = BLI_rcti_size_y(&rect_prog); - w = MAX2(w, min); - + w = MAX2(w, offs); + rect_bar.xmax = rect_bar.xmin + w; - - UI_draw_widget_scroll(wcol, &rect_prog, &rect_bar, UI_SCROLL_NO_OUTLINE); - + + round_box_edges(&wtb, roundboxalign, &rect_prog, offs); + round_box_edges(&wtb_bar, roundboxalign, &rect_bar, offs); + + wtb.draw_outline = true; + widgetbase_draw(&wtb, wcol); + + /* "slider" bar color */ + copy_v3_v3_char(wcol->inner, wcol->item); + widgetbase_draw(&wtb_bar, wcol); + /* raise text a bit */ - rect->ymin += 6 * UI_DPI_FAC; - rect->xmin -= 6 * UI_DPI_FAC; + rect->xmin += (BLI_rcti_size_x(&rect_prog) / 2); + rect->xmax += (BLI_rcti_size_x(&rect_prog) / 2); } static void widget_link(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index d272ff344a4..ad7d5c3ffcf 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -2024,7 +2024,7 @@ void init_userdef_do_versions(void) {0, 0, 0, 255}, {190, 190, 190, 255}, {100, 100, 100, 180}, - {68, 68, 68, 255}, + {128, 128, 128, 255}, {0, 0, 0, 255}, {255, 255, 255, 255}, @@ -2678,6 +2678,13 @@ void init_userdef_do_versions(void) } } + if (!USER_VERSION_ATLEAST(276, 8)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + rgba_char_args_set(btheme->tui.wcol_progress.item, 128, 128, 128, 255); + } + } + if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 62ac4b27915..b9e4f19c806 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -453,10 +453,14 @@ struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void bool WM_jobs_test(struct wmWindowManager *wm, void *owner, int job_type); float WM_jobs_progress(struct wmWindowManager *wm, void *owner); char *WM_jobs_name(struct wmWindowManager *wm, void *owner); +double WM_jobs_starttime(struct wmWindowManager *wm, void *owner); +char *WM_jobs_tooltip(struct wmWindowManager *wm, void *owner); +void WM_jobs_set_tooltip(struct wmWindowManager *wm, void *owner, char *text); void *WM_jobs_customdata(struct wmWindowManager *wm, void *owner); void *WM_jobs_customdata_from_type(struct wmWindowManager *wm, int job_type); bool WM_jobs_is_running(struct wmJob *); +bool WM_jobs_is_stopped(wmWindowManager *wm, void *owner); void *WM_jobs_customdata_get(struct wmJob *); void WM_jobs_customdata_set(struct wmJob *, void *customdata, void (*free)(void *)); void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned int endnote); diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index f8258d18c1a..72941d1b1da 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -103,7 +103,7 @@ struct wmJob { unsigned int note, endnote; -/* internal */ + /* internal */ void *owner; int flag; short suspended, running, ready, do_update, stop, job_type; @@ -112,6 +112,9 @@ struct wmJob { /* for display in header, identification */ char name[128]; + /* for other text display in progress bar */ + char text[128]; + /* once running, we store this separately */ void *run_customdata; void (*run_free)(void *); @@ -245,6 +248,38 @@ float WM_jobs_progress(wmWindowManager *wm, void *owner) return 0.0; } +/* time that job started */ +double WM_jobs_starttime(wmWindowManager *wm, void *owner) +{ + wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY); + + if (wm_job && wm_job->flag & WM_JOB_PROGRESS) + return wm_job->start_time; + + return 0; +} + +/* get progress bar tooltip text */ +char *WM_jobs_tooltip(wmWindowManager *wm, void *owner) +{ + wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY); + + if (wm_job && wm_job->flag & WM_JOB_PROGRESS) + return wm_job->text; + + return NULL; +} + +/* set progress bar text (e.g. tooltip, UI label, eta...) */ +void WM_jobs_set_tooltip(wmWindowManager *wm, void *owner, char *text) +{ + wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY); + + if (wm_job && wm_job->flag & WM_JOB_PROGRESS) { + BLI_strncpy(wm_job->text, text, sizeof(wm_job->text)); + } +} + char *WM_jobs_name(wmWindowManager *wm, void *owner) { wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY); @@ -280,6 +315,12 @@ bool WM_jobs_is_running(wmJob *wm_job) return wm_job->running; } +bool WM_jobs_is_stopped(wmWindowManager *wm, void *owner) +{ + wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY); + return wm_job->stop; +} + void *WM_jobs_customdata_get(wmJob *wm_job) { if (!wm_job->customdata) { @@ -420,8 +461,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) if (wm_job->wt == NULL) wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, wm_job->timestep); - if (G.debug & G_DEBUG_JOBS) - wm_job->start_time = PIL_check_seconds_timer(); + wm_job->start_time = PIL_check_seconds_timer(); } else { printf("job fails, not initialized\n"); |