Blender V5.0
interface_template_running_jobs.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <fmt/format.h>
10
11#include "BKE_context.hh"
12#include "BKE_global.hh"
13#include "BKE_main.hh"
14
15#include "BLI_listbase.h"
16#include "BLI_string_utf8.h"
17#include "BLI_time.h"
18
19#include "BLI_timecode.h"
20#include "BLT_translation.hh"
21
22#include "ED_screen.hh"
23
24#include "WM_api.hh"
25
27#include "interface_intern.hh"
28
29#define B_STOPRENDER 1
30#define B_STOPCAST 2
31#define B_STOPANIM 3
32#define B_STOPCOMPO 4
33#define B_STOPSEQ 5
34#define B_STOPCLIP 6
35#define B_STOPFILE 7
36#define B_STOPOTHER 8
37
38static void do_running_jobs(bContext *C, void * /*arg*/, int event)
39{
40 switch (event) {
41 case B_STOPRENDER:
42 G.is_break = true;
43 break;
44 case B_STOPCAST:
46 break;
47 case B_STOPANIM:
49 "SCREEN_OT_animation_play",
51 nullptr,
52 nullptr);
53 break;
54 case B_STOPCOMPO:
56 break;
57 case B_STOPSEQ:
59 break;
60 case B_STOPCLIP:
62 break;
63 case B_STOPFILE:
65 break;
66 case B_STOPOTHER:
67 G.is_break = true;
68 break;
69 }
70}
71
76
77static std::string progress_tooltip_func(bContext * /*C*/,
78 void *argN,
79 const blender::StringRef /*tip*/)
80{
81 ProgressTooltip_Store *arg = static_cast<ProgressTooltip_Store *>(argN);
82 wmWindowManager *wm = arg->wm;
83 void *owner = arg->owner;
84
85 const float progress = WM_jobs_progress(wm, owner);
86
87 /* create tooltip text and associate it with the job */
88 char elapsed_str[32];
89 char remaining_str[32] = "Unknown";
90 const double elapsed = BLI_time_now_seconds() - WM_jobs_starttime(wm, owner);
91 BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
92
93 if (progress) {
94 const double remaining = (elapsed / double(progress)) - elapsed;
95 BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining);
96 }
97
98 return fmt::format(
99 "Time Remaining: {}\n"
100 "Time Elapsed: {}",
101 remaining_str,
102 elapsed_str);
103}
104
106{
107 Main *bmain = CTX_data_main(C);
109 ScrArea *area = CTX_wm_area(C);
110 void *owner = nullptr;
111 int handle_event, icon = 0;
112 const char *op_name = nullptr;
113 const char *op_description = nullptr;
114
115 uiBlock *block = layout->block();
117
119
120 /* another scene can be rendering too, for example via compositor */
121 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
122 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) {
123 handle_event = B_STOPOTHER;
124 icon = ICON_NONE;
125 owner = scene;
126 }
127 else {
128 continue;
129 }
130
132 handle_event = B_STOPSEQ;
133 icon = ICON_SEQUENCE;
134 owner = scene;
135 break;
136 }
138 handle_event = B_STOPSEQ;
139 icon = ICON_SEQUENCE;
140 break;
141 }
143 handle_event = B_STOPSEQ;
144 icon = ICON_SEQUENCE;
145 break;
146 }
148 handle_event = B_STOPCLIP;
149 icon = ICON_TRACKER;
150 break;
151 }
152 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_CLIP_PREFETCH)) {
153 handle_event = B_STOPCLIP;
154 icon = ICON_TRACKER;
155 break;
156 }
158 handle_event = B_STOPCLIP;
159 icon = ICON_TRACKER;
160 break;
161 }
163 handle_event = B_STOPCLIP;
164 icon = ICON_TRACKER;
165 break;
166 }
169 {
170 handle_event = B_STOPFILE;
171 icon = ICON_FILEBROWSER;
172 break;
173 }
174 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) {
175 handle_event = B_STOPRENDER;
176 icon = ICON_SCENE;
177 if (U.render_display_type != USER_RENDER_DISPLAY_NONE) {
178 op_name = "RENDER_OT_view_show";
179 op_description = "Show the render window";
180 }
181 break;
182 }
183 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_COMPOSITE)) {
184 handle_event = B_STOPCOMPO;
185 icon = ICON_RENDERLAYERS;
186 break;
187 }
190 {
191 /* Skip bake jobs in compositor to avoid compo header displaying
192 * progress bar which is not being updated (bake jobs only need
193 * to update NC_IMAGE context.
194 */
195 if (area->spacetype != SPACE_NODE) {
196 handle_event = B_STOPOTHER;
197 icon = ICON_IMAGE;
198 break;
199 }
200 continue;
201 }
202 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_DPAINT_BAKE)) {
203 handle_event = B_STOPOTHER;
204 icon = ICON_MOD_DYNAMICPAINT;
205 break;
206 }
207 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_POINTCACHE)) {
208 handle_event = B_STOPOTHER;
209 icon = ICON_PHYSICS;
210 break;
211 }
213 handle_event = B_STOPOTHER;
214 icon = ICON_MOD_FLUIDSIM;
215 break;
216 }
218 handle_event = B_STOPOTHER;
219 icon = ICON_MOD_OCEAN;
220 break;
221 }
222 }
223
224 if (owner) {
225 const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
226 const bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner));
227
228 uiLayout *row = &layout->row(false);
229 block = row->block();
230
231 /* get percentage done and set it as the UI text */
232 const float progress = WM_jobs_progress(wm, owner);
233 char text[8];
234 SNPRINTF_UTF8(text, "%d%%", int(progress * 100));
235
236 const char *name = active ? RPT_(WM_jobs_name(wm, owner)) : RPT_("Canceling...");
237
238 /* job icon as a button */
239 if (op_name) {
240 uiDefIconButO(block,
242 op_name,
244 icon,
245 0,
246 0,
247 UI_UNIT_X,
248 UI_UNIT_Y,
249 TIP_(op_description));
250 }
251
252 /* job name and icon if not previously set */
253 const int textwidth = UI_fontstyle_string_width(fstyle, name);
254 uiDefIconTextBut(block,
256 0,
257 op_name ? 0 : icon,
258 name,
259 0,
260 0,
261 textwidth + UI_UNIT_X * 1.5f,
262 UI_UNIT_Y,
263 nullptr,
264 "");
265
266 /* stick progress bar and cancel button together */
267 row = &layout->row(true);
268 row->active_set(active);
269 block = row->block();
270
271 {
272 ProgressTooltip_Store *tip_arg = static_cast<ProgressTooltip_Store *>(
273 MEM_mallocN(sizeof(*tip_arg), __func__));
274 tip_arg->wm = wm;
275 tip_arg->owner = owner;
276 uiButProgress *but_progress = (uiButProgress *)uiDefIconTextBut(block,
278 0,
279 ICON_NONE,
280 text,
281 UI_UNIT_X,
282 0,
283 UI_UNIT_X * 6.0f,
284 UI_UNIT_Y,
285 nullptr,
286 nullptr);
287
288 but_progress->progress_factor = progress;
290 }
291
292 if (!wm->runtime->is_interface_locked) {
293 uiDefIconTextBut(block,
295 handle_event,
296 ICON_PANEL_CLOSE,
297 "",
298 0,
299 0,
300 UI_UNIT_X,
301 UI_UNIT_Y,
302 nullptr,
303 TIP_("Stop this job"));
304 }
305 }
306
308 uiDefIconTextBut(block,
311 ICON_CANCEL,
312 IFACE_("Anim Player"),
313 0,
314 0,
315 UI_UNIT_X * 5.0f,
316 UI_UNIT_Y,
317 nullptr,
318 TIP_("Stop animation playback"));
319 }
320}
bScreen * CTX_wm_screen(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
#define LISTBASE_FOREACH(type, var, list)
#define SNPRINTF_UTF8(dst, format,...)
Platform independent time functions.
double BLI_time_now_seconds(void)
Definition time.cc:113
size_t BLI_timecode_string_from_time_simple(char *str, size_t maxncpy, double time_seconds) ATTR_NONNULL()
Definition timecode.cc:170
#define RPT_(msgid)
#define TIP_(msgid)
#define IFACE_(msgid)
@ SPACE_NODE
@ USER_RENDER_DISPLAY_NONE
bScreen * ED_screen_animation_no_scrub(const wmWindowManager *wm)
#define C
Definition RandGen.cpp:29
uiBut * uiDefIconTextBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, int icon, blender::StringRef str, int x, int y, short width, short height, void *poin, std::optional< blender::StringRef > tip)
#define UI_UNIT_Y
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg)
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
uiBut * uiDefIconButO(uiBlock *block, ButType type, blender::StringRefNull opname, blender::wm::OpCallContext opcontext, int icon, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define UI_FSTYLE_WIDGET
#define UI_UNIT_X
@ WM_JOB_TYPE_DPAINT_BAKE
Definition WM_api.hh:1795
@ WM_JOB_TYPE_SEQ_BUILD_PROXY
Definition WM_api.hh:1792
@ WM_JOB_TYPE_COMPOSITE
Definition WM_api.hh:1777
@ WM_JOB_TYPE_OBJECT_BAKE
Definition WM_api.hh:1785
@ WM_JOB_TYPE_POINTCACHE
Definition WM_api.hh:1794
@ WM_JOB_TYPE_SEQ_DRAW_THUMBNAIL
Definition WM_api.hh:1807
@ WM_JOB_TYPE_ASSET_LIBRARY_LOAD
Definition WM_api.hh:1787
@ WM_JOB_TYPE_CLIP_BUILD_PROXY
Definition WM_api.hh:1788
@ WM_JOB_TYPE_CLIP_PREFETCH
Definition WM_api.hh:1791
@ WM_JOB_TYPE_SEQ_BUILD_PREVIEW
Definition WM_api.hh:1793
@ WM_JOB_TYPE_RENDER
Definition WM_api.hh:1778
@ WM_JOB_TYPE_ANY
Definition WM_api.hh:1775
@ WM_JOB_TYPE_OBJECT_SIM_OCEAN
Definition WM_api.hh:1782
@ WM_JOB_TYPE_CLIP_SOLVE_CAMERA
Definition WM_api.hh:1790
@ WM_JOB_TYPE_FILESEL_READDIR
Definition WM_api.hh:1786
@ WM_JOB_TYPE_CLIP_TRACK_MARKERS
Definition WM_api.hh:1789
@ WM_JOB_TYPE_OBJECT_SIM_FLUID
Definition WM_api.hh:1783
@ WM_JOB_TYPE_OBJECT_BAKE_TEXTURE
Definition WM_api.hh:1784
#define U
#define active
static void do_running_jobs(bContext *C, void *, int event)
void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
static std::string progress_tooltip_func(bContext *, void *argN, const blender::StringRef)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void block_layout_set_current(uiBlock *block, uiLayout *layout)
const char * name
ListBase scenes
Definition BKE_main.hh:278
uiBlock * block() const
void active_set(bool active)
uiLayout & row(bool align)
WindowManagerRuntimeHandle * runtime
wmOperatorStatus WM_operator_name_call(bContext *C, const char *opstring, blender::wm::OpCallContext context, PointerRNA *properties, const wmEvent *event)
void WM_jobs_stop_all_from_owner(wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:663
const char * WM_jobs_name(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:319
bool WM_jobs_is_stopped(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:346
float WM_jobs_progress(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:267
double WM_jobs_starttime(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:308
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:247