UI: add progress indicator variations & RNA API
Add pie and ring styles of progress indicators. Exposes progress bar to the Python API and adds a "type" property to allow style variation. This can be used for scripts & add-ons to show progress in the UI. Ref !109882. Co-authored-by: Campbell Barton <campbell@blender.org>
This commit is contained in:
parent
e63a77eeb8
commit
c6adafd8ef
@ -1450,6 +1450,12 @@ enum {
|
||||
UI_TEMPLATE_ID_FILTER_AVAILABLE = 1,
|
||||
};
|
||||
|
||||
enum eButProgressType {
|
||||
UI_BUT_PROGRESS_TYPE_BAR = 0,
|
||||
UI_BUT_PROGRESS_TYPE_RING = 1,
|
||||
UI_BUT_PROGRESS_TYPE_PIE = 2,
|
||||
};
|
||||
|
||||
/***************************** ID Utilities *******************************/
|
||||
|
||||
int UI_icon_from_id(const struct ID *id);
|
||||
@ -2882,6 +2888,11 @@ void uiItemS_ex(uiLayout *layout, float factor);
|
||||
/** Flexible spacing. */
|
||||
void uiItemSpacer(uiLayout *layout);
|
||||
|
||||
void uiItemProgressIndicator(uiLayout *layout,
|
||||
const char *text,
|
||||
float factor,
|
||||
enum eButProgressType progress_type);
|
||||
|
||||
/* popover */
|
||||
void uiItemPopoverPanel_ptr(
|
||||
uiLayout *layout, const struct bContext *C, struct PanelType *pt, const char *name, int icon);
|
||||
|
@ -345,6 +345,8 @@ struct uiButDecorator : public uiBut {
|
||||
struct uiButProgress : public uiBut {
|
||||
/** Progress in 0..1 range */
|
||||
float progress_factor = 0.0f;
|
||||
/** The display style (bar, pie... etc). */
|
||||
eButProgressType progress_type = UI_BUT_PROGRESS_TYPE_BAR;
|
||||
};
|
||||
|
||||
struct uiButViewItem : public uiBut {
|
||||
|
@ -3475,6 +3475,51 @@ void uiItemS(uiLayout *layout)
|
||||
uiItemS_ex(layout, 1.0f);
|
||||
}
|
||||
|
||||
void uiItemProgressIndicator(uiLayout *layout,
|
||||
const char *text,
|
||||
const float factor,
|
||||
const eButProgressType progress_type)
|
||||
{
|
||||
const bool has_text = text && text[0];
|
||||
uiBlock *block = layout->root->block;
|
||||
short width;
|
||||
|
||||
if (progress_type == UI_BUT_PROGRESS_TYPE_BAR) {
|
||||
width = UI_UNIT_X * 5;
|
||||
}
|
||||
else if (has_text) {
|
||||
width = UI_UNIT_X * 8;
|
||||
}
|
||||
else {
|
||||
width = UI_UNIT_X;
|
||||
}
|
||||
|
||||
UI_block_layout_set_current(block, layout);
|
||||
uiBut *but = uiDefBut(block,
|
||||
UI_BTYPE_PROGRESS,
|
||||
0,
|
||||
(text) ? text : "",
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
short(UI_UNIT_Y),
|
||||
nullptr,
|
||||
0.0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
|
||||
if (has_text && ELEM(progress_type, UI_BUT_PROGRESS_TYPE_RING, UI_BUT_PROGRESS_TYPE_PIE)) {
|
||||
/* For progress bar, centered is okay, left aligned for ring/pie. */
|
||||
but->drawflag |= UI_BUT_TEXT_LEFT;
|
||||
}
|
||||
|
||||
uiButProgress *progress_bar = static_cast<uiButProgress *>(but);
|
||||
progress_bar->progress_type = eButProgressType(progress_type);
|
||||
progress_bar->progress_factor = factor;
|
||||
}
|
||||
|
||||
void uiItemSpacer(uiLayout *layout)
|
||||
{
|
||||
uiBlock *block = layout->root->block;
|
||||
|
@ -3604,14 +3604,12 @@ static void widget_scroll(uiBut *but,
|
||||
UI_draw_widget_scroll(wcol, rect, &rect1, (state->but_flag & UI_SELECT) ? UI_SCROLL_PRESSED : 0);
|
||||
}
|
||||
|
||||
static void widget_progress_indicator(uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo * /*state*/,
|
||||
int roundboxalign,
|
||||
const float zoom)
|
||||
static void widget_progress_type_bar(uiButProgress *but_progress,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
int roundboxalign,
|
||||
const float zoom)
|
||||
{
|
||||
uiButProgress *but_progress = (uiButProgress *)but;
|
||||
rcti rect_prog = *rect, rect_bar = *rect;
|
||||
|
||||
uiWidgetBase wtb, wtb_bar;
|
||||
@ -3619,9 +3617,9 @@ static void widget_progress_indicator(uiBut *but,
|
||||
widget_init(&wtb_bar);
|
||||
|
||||
/* round corners */
|
||||
const float value = but_progress->progress_factor;
|
||||
const float factor = but_progress->progress_factor;
|
||||
const float ofs = widget_radius_from_zoom(zoom, wcol);
|
||||
float w = value * BLI_rcti_size_x(&rect_prog);
|
||||
float w = factor * BLI_rcti_size_x(&rect_prog);
|
||||
|
||||
/* Ensure minimum size. */
|
||||
w = MAX2(w, ofs);
|
||||
@ -3639,6 +3637,67 @@ static void widget_progress_indicator(uiBut *but,
|
||||
widgetbase_draw(&wtb_bar, wcol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for both ring & pie types.
|
||||
*/
|
||||
static void widget_progress_type_circle(uiButProgress *but_progress,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const float ring_width)
|
||||
{
|
||||
const float outer_rad = (rect->ymax - rect->ymin) / 2.0f;
|
||||
const float inner_rad = outer_rad * ring_width;
|
||||
const float x = rect->xmin + outer_rad;
|
||||
const float y = rect->ymin + outer_rad;
|
||||
const float start = 0.0f;
|
||||
const float end = but_progress->progress_factor * 360.0f;
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor3ubvAlpha(wcol->item, 255 / UI_PIXEL_AA_JITTER * 2);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
for (int i = 0; i < UI_PIXEL_AA_JITTER; i++) {
|
||||
imm_draw_disk_partial_fill_2d(pos,
|
||||
x + ui_pixel_jitter[i][0],
|
||||
y + ui_pixel_jitter[i][1],
|
||||
inner_rad,
|
||||
outer_rad,
|
||||
48,
|
||||
start,
|
||||
end);
|
||||
}
|
||||
immUnbindProgram();
|
||||
|
||||
if (but_progress->drawstr[0]) {
|
||||
rect->xmin += UI_UNIT_X;
|
||||
}
|
||||
}
|
||||
|
||||
static void widget_progress_indicator(uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo * /*state*/,
|
||||
int roundboxalign,
|
||||
const float zoom)
|
||||
{
|
||||
uiButProgress *but_progress = static_cast<uiButProgress *>(but);
|
||||
switch (but_progress->progress_type) {
|
||||
case UI_BUT_PROGRESS_TYPE_BAR: {
|
||||
widget_progress_type_bar(but_progress, wcol, rect, roundboxalign, zoom);
|
||||
break;
|
||||
}
|
||||
case UI_BUT_PROGRESS_TYPE_PIE: {
|
||||
widget_progress_type_circle(but_progress, wcol, rect, 0.6f);
|
||||
break;
|
||||
}
|
||||
case UI_BUT_PROGRESS_TYPE_RING: {
|
||||
widget_progress_type_circle(but_progress, wcol, rect, 0.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void widget_view_item(uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo *state,
|
||||
|
@ -470,6 +470,20 @@ static void rna_uiItemPopoverPanelFromGroup(uiLayout *layout,
|
||||
uiItemPopoverPanelFromGroup(layout, C, space_id, region_id, context, category);
|
||||
}
|
||||
|
||||
static void rna_uiItemProgress(struct uiLayout *layout,
|
||||
const char *text,
|
||||
const char *text_ctxt,
|
||||
bool translate,
|
||||
float factor,
|
||||
int progress_type)
|
||||
{
|
||||
if (translate && BLT_translate_iface()) {
|
||||
text = BLT_pgettext((text_ctxt && text_ctxt[0]) ? text_ctxt : BLT_I18NCONTEXT_DEFAULT, text);
|
||||
}
|
||||
|
||||
uiItemProgressIndicator(layout, text, factor, eButProgressType(progress_type));
|
||||
}
|
||||
|
||||
static void rna_uiTemplateID(uiLayout *layout,
|
||||
bContext *C,
|
||||
PointerRNA *ptr,
|
||||
@ -942,6 +956,13 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem progress_type_items[] = {
|
||||
{UI_BUT_PROGRESS_TYPE_BAR, "BAR", 0, "Bar", ""},
|
||||
{UI_BUT_PROGRESS_TYPE_RING, "RING", 0, "Ring", ""},
|
||||
{UI_BUT_PROGRESS_TYPE_PIE, "PIE", 0, "Pie", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem asset_view_template_options[] = {
|
||||
{UI_TEMPLATE_ASSET_DRAW_NO_NAMES,
|
||||
"NO_NAMES",
|
||||
@ -1335,6 +1356,25 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
RNA_def_function_ui_description(
|
||||
func, "Item. Inserts horizontal spacing empty space into the layout between items");
|
||||
|
||||
func = RNA_def_function(srna, "progress", "rna_uiItemProgress");
|
||||
RNA_def_function_ui_description(func, "Progress indicator");
|
||||
api_ui_item_common_text(func);
|
||||
RNA_def_float(func,
|
||||
"factor",
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
"Factor",
|
||||
"Amount of progress from 0.0f to 1.0f",
|
||||
0.0f,
|
||||
1.0f);
|
||||
RNA_def_enum(func,
|
||||
"type",
|
||||
progress_type_items,
|
||||
UI_BUT_PROGRESS_TYPE_BAR,
|
||||
"Type",
|
||||
"The type of progress indicator");
|
||||
|
||||
/* context */
|
||||
func = RNA_def_function(srna, "context_pointer_set", "uiLayoutSetContextPointer");
|
||||
parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of entry in the context");
|
||||
|
Loading…
Reference in New Issue
Block a user