Blender V4.5
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.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
26#include "UI_interface.hh"
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:
48 WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, nullptr, nullptr);
49 break;
50 case B_STOPCOMPO:
52 break;
53 case B_STOPSEQ:
55 break;
56 case B_STOPCLIP:
58 break;
59 case B_STOPFILE:
61 break;
62 case B_STOPOTHER:
63 G.is_break = true;
64 break;
65 }
66}
67
72
73static std::string progress_tooltip_func(bContext * /*C*/,
74 void *argN,
75 const blender::StringRef /*tip*/)
76{
77 ProgressTooltip_Store *arg = static_cast<ProgressTooltip_Store *>(argN);
78 wmWindowManager *wm = arg->wm;
79 void *owner = arg->owner;
80
81 const float progress = WM_jobs_progress(wm, owner);
82
83 /* create tooltip text and associate it with the job */
84 char elapsed_str[32];
85 char remaining_str[32] = "Unknown";
86 const double elapsed = BLI_time_now_seconds() - WM_jobs_starttime(wm, owner);
87 BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
88
89 if (progress) {
90 const double remaining = (elapsed / double(progress)) - elapsed;
91 BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining);
92 }
93
94 return fmt::format(
95 "Time Remaining: {}\n"
96 "Time Elapsed: {}",
97 remaining_str,
98 elapsed_str);
99}
100
102{
103 Main *bmain = CTX_data_main(C);
105 ScrArea *area = CTX_wm_area(C);
106 void *owner = nullptr;
107 int handle_event, icon = 0;
108 const char *op_name = nullptr;
109 const char *op_description = nullptr;
110
111 uiBlock *block = uiLayoutGetBlock(layout);
112 UI_block_layout_set_current(block, layout);
113
115
116 /* another scene can be rendering too, for example via compositor */
117 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
118 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) {
119 handle_event = B_STOPOTHER;
120 icon = ICON_NONE;
121 owner = scene;
122 }
123 else {
124 continue;
125 }
126
128 handle_event = B_STOPSEQ;
129 icon = ICON_SEQUENCE;
130 owner = scene;
131 break;
132 }
134 handle_event = B_STOPSEQ;
135 icon = ICON_SEQUENCE;
136 break;
137 }
139 handle_event = B_STOPSEQ;
140 icon = ICON_SEQUENCE;
141 break;
142 }
144 handle_event = B_STOPCLIP;
145 icon = ICON_TRACKER;
146 break;
147 }
148 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_CLIP_PREFETCH)) {
149 handle_event = B_STOPCLIP;
150 icon = ICON_TRACKER;
151 break;
152 }
154 handle_event = B_STOPCLIP;
155 icon = ICON_TRACKER;
156 break;
157 }
159 handle_event = B_STOPCLIP;
160 icon = ICON_TRACKER;
161 break;
162 }
165 {
166 handle_event = B_STOPFILE;
167 icon = ICON_FILEBROWSER;
168 break;
169 }
170 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) {
171 handle_event = B_STOPRENDER;
172 icon = ICON_SCENE;
173 if (U.render_display_type != USER_RENDER_DISPLAY_NONE) {
174 op_name = "RENDER_OT_view_show";
175 op_description = "Show the render window";
176 }
177 break;
178 }
179 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_COMPOSITE)) {
180 handle_event = B_STOPCOMPO;
181 icon = ICON_RENDERLAYERS;
182 break;
183 }
186 {
187 /* Skip bake jobs in compositor to avoid compo header displaying
188 * progress bar which is not being updated (bake jobs only need
189 * to update NC_IMAGE context.
190 */
191 if (area->spacetype != SPACE_NODE) {
192 handle_event = B_STOPOTHER;
193 icon = ICON_IMAGE;
194 break;
195 }
196 continue;
197 }
198 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_DPAINT_BAKE)) {
199 handle_event = B_STOPOTHER;
200 icon = ICON_MOD_DYNAMICPAINT;
201 break;
202 }
203 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_POINTCACHE)) {
204 handle_event = B_STOPOTHER;
205 icon = ICON_PHYSICS;
206 break;
207 }
209 handle_event = B_STOPOTHER;
210 icon = ICON_MOD_FLUIDSIM;
211 break;
212 }
214 handle_event = B_STOPOTHER;
215 icon = ICON_MOD_OCEAN;
216 break;
217 }
218 }
219
220 if (owner) {
221 const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
222 const bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner));
223
224 uiLayout *row = &layout->row(false);
225 block = uiLayoutGetBlock(row);
226
227 /* get percentage done and set it as the UI text */
228 const float progress = WM_jobs_progress(wm, owner);
229 char text[8];
230 SNPRINTF(text, "%d%%", int(progress * 100));
231
232 const char *name = active ? RPT_(WM_jobs_name(wm, owner)) : RPT_("Canceling...");
233
234 /* job icon as a button */
235 if (op_name) {
236 uiDefIconButO(block,
238 op_name,
240 icon,
241 0,
242 0,
243 UI_UNIT_X,
244 UI_UNIT_Y,
245 TIP_(op_description));
246 }
247
248 /* job name and icon if not previously set */
249 const int textwidth = UI_fontstyle_string_width(fstyle, name);
250 uiDefIconTextBut(block,
252 0,
253 op_name ? 0 : icon,
254 name,
255 0,
256 0,
257 textwidth + UI_UNIT_X * 1.5f,
258 UI_UNIT_Y,
259 nullptr,
260 0.0f,
261 0.0f,
262 "");
263
264 /* stick progress bar and cancel button together */
265 row = &layout->row(true);
267 block = uiLayoutGetBlock(row);
268
269 {
270 ProgressTooltip_Store *tip_arg = static_cast<ProgressTooltip_Store *>(
271 MEM_mallocN(sizeof(*tip_arg), __func__));
272 tip_arg->wm = wm;
273 tip_arg->owner = owner;
274 uiButProgress *but_progress = (uiButProgress *)uiDefIconTextBut(block,
276 0,
277 ICON_NONE,
278 text,
279 UI_UNIT_X,
280 0,
281 UI_UNIT_X * 6.0f,
282 UI_UNIT_Y,
283 nullptr,
284 0.0f,
285 0.0f,
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 0.0f,
304 0.0f,
305 TIP_("Stop this job"));
306 }
307 }
308
310 uiDefIconTextBut(block,
313 ICON_CANCEL,
314 IFACE_("Anim Player"),
315 0,
316 0,
317 UI_UNIT_X * 5.0f,
318 UI_UNIT_Y,
319 nullptr,
320 0.0f,
321 0.0f,
322 TIP_("Stop animation playback"));
323 }
324}
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(dst, format,...)
Definition BLI_string.h:599
Platform independent time functions.
double BLI_time_now_seconds(void)
Definition time.cc:65
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
#define UI_UNIT_Y
uiBut * uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
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, int type, blender::StringRefNull opname, wmOperatorCallContext 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
@ UI_BTYPE_BUT
@ UI_BTYPE_PROGRESS
@ UI_BTYPE_LABEL
void uiLayoutSetActive(uiLayout *layout, bool active)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
@ WM_JOB_TYPE_DPAINT_BAKE
Definition WM_api.hh:1745
@ WM_JOB_TYPE_SEQ_BUILD_PROXY
Definition WM_api.hh:1742
@ WM_JOB_TYPE_COMPOSITE
Definition WM_api.hh:1727
@ WM_JOB_TYPE_OBJECT_BAKE
Definition WM_api.hh:1735
@ WM_JOB_TYPE_POINTCACHE
Definition WM_api.hh:1744
@ WM_JOB_TYPE_SEQ_DRAW_THUMBNAIL
Definition WM_api.hh:1757
@ WM_JOB_TYPE_ASSET_LIBRARY_LOAD
Definition WM_api.hh:1737
@ WM_JOB_TYPE_CLIP_BUILD_PROXY
Definition WM_api.hh:1738
@ WM_JOB_TYPE_CLIP_PREFETCH
Definition WM_api.hh:1741
@ WM_JOB_TYPE_SEQ_BUILD_PREVIEW
Definition WM_api.hh:1743
@ WM_JOB_TYPE_RENDER
Definition WM_api.hh:1728
@ WM_JOB_TYPE_ANY
Definition WM_api.hh:1725
@ WM_JOB_TYPE_OBJECT_SIM_OCEAN
Definition WM_api.hh:1732
@ WM_JOB_TYPE_CLIP_SOLVE_CAMERA
Definition WM_api.hh:1740
@ WM_JOB_TYPE_FILESEL_READDIR
Definition WM_api.hh:1736
@ WM_JOB_TYPE_CLIP_TRACK_MARKERS
Definition WM_api.hh:1739
@ WM_JOB_TYPE_OBJECT_SIM_FLUID
Definition WM_api.hh:1733
@ WM_JOB_TYPE_OBJECT_BAKE_TEXTURE
Definition WM_api.hh:1734
@ WM_OP_INVOKE_SCREEN
Definition WM_types.hh:243
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:238
float progress
Definition WM_types.hh:1019
#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)
ListBase scenes
Definition BKE_main.hh:245
uiLayout & row(bool align)
WindowManagerRuntimeHandle * runtime
wmOperatorStatus WM_operator_name_call(bContext *C, const char *opstring, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
void WM_jobs_stop_all_from_owner(wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:638
const char * WM_jobs_name(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:296
bool WM_jobs_is_stopped(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:323
float WM_jobs_progress(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:244
double WM_jobs_starttime(const wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:285
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:224