UI: improve percentage display for wm.progress API

wm.progress displayed a percentage in a cryptic
2x2 grid of numbers, so:

```
75
23
```

Represents `75.23%`. This is now shown as `75.23%`
on systems that support RGBA cursors.
This commit is contained in:
Campbell Barton
2025-07-27 21:26:26 +10:00
parent 8355451700
commit ca0e6e77ec
3 changed files with 51 additions and 15 deletions

View File

@@ -201,12 +201,12 @@ static void rna_progress_begin(wmWindowManager * /*wm*/, float min, float max)
static void rna_progress_update(wmWindowManager *wm, float value)
{
if (wm_progress_state.is_valid) {
/* Map to cursor_time range [0,9999] */
/* Map to factor 0..1. */
wmWindow *win = wm->winactive;
if (win) {
int val = int(10000 * (value - wm_progress_state.min) /
(wm_progress_state.max - wm_progress_state.min));
WM_cursor_time(win, val);
const float progress_factor = (value - wm_progress_state.min) /
(wm_progress_state.max - wm_progress_state.min);
WM_cursor_progress(win, progress_factor);
}
}
}

View File

@@ -527,6 +527,11 @@ void WM_cursor_grab_disable(wmWindow *win, const int mouse_ungrab_xy[2]);
*/
void WM_cursor_time(wmWindow *win, int nr);
/**
* Show progress in the cursor (0.0..1.0 when complete).
*/
void WM_cursor_progress(wmWindow *win, float progress_factor);
wmPaintCursor *WM_paint_cursor_activate(short space_type,
short region_type,
bool (*poll)(bContext *C),

View File

@@ -52,6 +52,12 @@
*/
constexpr int CURSOR_HARDWARE_SIZE_MAX = 255;
/**
* The maximum size of cursor text (in bytes).
* Can remain small as it's unlikely we can ever show much text in a cursor.
*/
#define CURSOR_TEXT_BUFFER_SIZE 24
/** Blender custom cursor. */
struct BCursor {
/**
@@ -729,7 +735,7 @@ static void wm_cursor_time_small(wmWindow *win, uint32_t nr)
* \return the pixel data as a `sizeof(uint8_t[4]) * r_bitmap_size[0] * r_bitmap_size[1]` array
* or null on failure.
*/
static uint8_t *cursor_bitmap_from_text(const std::string &text,
static uint8_t *cursor_bitmap_from_text(const char *text,
const int cursor_size,
const int cursor_size_max,
int font_id,
@@ -746,8 +752,9 @@ static uint8_t *cursor_bitmap_from_text(const std::string &text,
int font_descender;
/* At least 1 even on an empty string else the cursor is blank. */
const int text_units = std::max(1, BLI_str_utf8_column_count(text.c_str(), text.size()));
const bool text_to_draw = text.size() > 0;
const size_t text_len = strlen(text);
const int text_units = std::max(1, BLI_str_utf8_column_count(text, text_len));
const bool text_to_draw = text_len != 0;
for (int pass = 0; pass < 2; pass++) {
BLF_size(font_id, font_size);
@@ -791,7 +798,7 @@ static uint8_t *cursor_bitmap_from_text(const std::string &text,
BLF_buffer_col(font_id, color);
BLF_buffer(font_id, nullptr, bitmap_rgba, dest_size[0], dest_size[1], nullptr);
BLF_position(font_id, font_padding, font_padding + font_descender, 0.0f);
BLF_draw_buffer(font_id, text.c_str(), text.size());
BLF_draw_buffer(font_id, text, text_len);
BLF_buffer(font_id, nullptr, nullptr, 0, 0, nullptr);
cursor_bitmap_rgba_flip_y(bitmap_rgba, dest_size);
@@ -803,10 +810,10 @@ static uint8_t *cursor_bitmap_from_text(const std::string &text,
return bitmap_rgba;
}
static bool wm_cursor_text_generator(wmWindow *win, const std::string &text, int font_id)
static bool wm_cursor_text_generator(wmWindow *win, const char *text, int font_id)
{
struct WMCursorText {
std::string text;
char text[CURSOR_TEXT_BUFFER_SIZE];
int font_id;
};
@@ -845,7 +852,7 @@ static bool wm_cursor_text_generator(wmWindow *win, const std::string &text, int
};
WMCursorText *cursor_text = MEM_new<WMCursorText>(__func__);
cursor_text->text = text;
STRNCPY_UTF8(cursor_text->text, text);
cursor_text->font_id = font_id;
cursor_generator->user_data = (void *)cursor_text;
@@ -861,7 +868,7 @@ static bool wm_cursor_text_generator(wmWindow *win, const std::string &text, int
return (success == GHOST_kSuccess) ? true : false;
}
static bool wm_cursor_text_pixmap(wmWindow *win, const std::string &text, int font_id)
static bool wm_cursor_text_pixmap(wmWindow *win, const char *text, int font_id)
{
const int cursor_size = wm_cursor_size(win);
/* This is arbitrary. Use a larger value than the cursor size since the text is often wider than
@@ -899,7 +906,7 @@ static bool wm_cursor_text_pixmap(wmWindow *win, const std::string &text, int fo
return (success == GHOST_kSuccess) ? true : false;
}
static bool wm_cursor_text(wmWindow *win, const std::string &text, int font_id)
static bool wm_cursor_text(wmWindow *win, const char *text, int font_id)
{
if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_GENERATOR) {
return wm_cursor_text_generator(win, text, font_id);
@@ -907,7 +914,11 @@ static bool wm_cursor_text(wmWindow *win, const std::string &text, int font_id)
return wm_cursor_text_pixmap(win, text, font_id);
}
void WM_cursor_time(wmWindow *win, int nr)
/**
* \param is_percentage: When true, nr represents a percentage multiplied by 100
* so the percentage with two decimal places can be shown.
*/
static void wm_cursor_number_impl(wmWindow *win, int nr, bool is_percentage)
{
if (win->lastcursor == 0) {
win->lastcursor = win->cursor;
@@ -919,7 +930,15 @@ void WM_cursor_time(wmWindow *win, int nr)
const uint32_t nr_abs = nr >= 0 ? uint32_t(nr) : -uint32_t(nr);
if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_RGBA) {
wm_cursor_text(win, std::to_string(nr_abs), blf_mono_font);
char text[CURSOR_TEXT_BUFFER_SIZE];
if (is_percentage) {
/* Left pad to avoid resizing text between 9% & 10%. */
SNPRINTF_UTF8(text, "%2u.%02u", nr_abs / 100, nr_abs % 100);
}
else {
SNPRINTF_UTF8(text, "%u", nr_abs);
}
wm_cursor_text(win, text, blf_mono_font);
}
else if (wm_cursor_size(win) < 24 || !wm_cursor_time_large(win, nr_abs)) {
wm_cursor_time_small(win, nr_abs);
@@ -929,6 +948,18 @@ void WM_cursor_time(wmWindow *win, int nr)
win->cursor = 0;
}
void WM_cursor_time(wmWindow *win, int nr)
{
wm_cursor_number_impl(win, nr, false);
}
void WM_cursor_progress(wmWindow *win, float progress_factor)
{
constexpr int nr_max = 10000;
const int nr = std::clamp(int(std::round(double(progress_factor) * nr_max)), 0, nr_max);
wm_cursor_number_impl(win, nr, true);
}
#ifndef WITH_HEADLESS
static void wm_add_cursor(WMCursorType cursor,
const char *svg_source,