Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-11-18 23:14:11 +0300
committerHans Goudey <h.goudey@me.com>2020-11-18 23:14:11 +0300
commit0d93bd8d63980f1188e226daba2ba781b8b33658 (patch)
tree62004729a78503c3bcad3d1b1439b416c6b909b1
parentd6d79653073944d58930717f6da2f35c38e49061 (diff)
UI Code Quality: Refactor panel drawing function
The existing panel drawing function was a bit convoluted with dependent conditions in different scopes, redundant and unecessary computations, and un-helpful naming. This commit separates the function into two parts, the backdrop and the widgets. It also improves naming and uses const where possible, and in general cleans up the code. There are some slight visual changes, mostly with the placement of the drag icon, which moves a bit downward to be centered with the triangle icon. The black rectangle displayed while dragging is also removed.
-rw-r--r--source/blender/editors/interface/interface_panel.c409
1 files changed, 185 insertions, 224 deletions
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 6b6d9a76313..26fea3ca1a5 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1062,265 +1062,226 @@ void UI_panel_label_offset(const uiBlock *block, int *r_x, int *r_y)
}
}
-static void ui_draw_aligned_panel_header(const uiStyle *style,
- const uiBlock *block,
- const rcti *rect,
- const bool show_background,
- const bool region_search_filter_active)
-{
- const Panel *panel = block->panel;
- const bool is_subpanel = (panel->type && panel->type->parent);
+static void panel_draw_aligned_widgets(const uiStyle *style,
+ const Panel *panel,
+ const rcti *header_rect,
+ const float aspect,
+ const bool show_pin,
+ const bool show_background,
+ const bool region_search_filter_active)
+{
+ const bool is_subpanel = panel->type->parent != NULL;
const uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle;
- /* + 0.001f to avoid flirting with float inaccuracy .*/
- const int pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f;
-
- /* Draw text labels. */
- uchar col_title[4];
- panel_title_color_get(panel, show_background, region_search_filter_active, col_title);
- col_title[3] = 255;
-
- rcti hrect = *rect;
- hrect.xmin = rect->xmin + pnl_icons;
- hrect.ymin -= 2.0f / block->aspect;
- UI_fontstyle_draw(fontstyle,
- &hrect,
- panel->drawname,
- col_title,
- &(struct uiFontStyleDraw_Params){
- .align = UI_STYLE_TEXT_LEFT,
- });
-}
-
-/**
- * Draw a panel integrated in buttons-window, tool/property lists etc.
- */
-void ui_draw_aligned_panel(const uiStyle *style,
- const uiBlock *block,
- const rcti *rect,
- const bool show_pin,
- const bool show_background,
- const bool region_search_filter_active)
-{
- const Panel *panel = block->panel;
- float color[4];
- const bool is_subpanel = (panel->type && panel->type->parent);
- const bool show_drag = (!is_subpanel &&
- /* FIXME(campbell): currently no background means floating panel which
- * can't be dragged. This may be changed in future. */
- show_background);
- const int panel_col = is_subpanel ? TH_PANEL_SUB_BACK : TH_PANEL_BACK;
- const bool draw_box_style = (panel->type && panel->type->flag & PANEL_TYPE_DRAW_BOX);
-
- /* Use the theme for box widgets for box-style panels. */
- uiWidgetColors *box_wcol = NULL;
- if (draw_box_style) {
- bTheme *btheme = UI_GetTheme();
- box_wcol = &btheme->tui.wcol_box;
- }
-
- const uint pos = GPU_vertformat_attr_add(
- immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ const int header_height = BLI_rcti_size_y(header_rect);
+ const int scaled_unit = round_fl_to_int(UI_UNIT_X / aspect);
- if (panel->type && (panel->type->flag & PANEL_TYPE_NO_HEADER)) {
- if (show_background) {
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColor(panel_col);
- immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- immUnbindProgram();
- }
- return;
- }
-
- /* Calculate header rectangle with + 0.001f to prevent flicker due to float inaccuracy. */
- rcti headrect = {
- rect->xmin, rect->xmax, rect->ymax, rect->ymax + floor(PNL_HEADER / block->aspect + 0.001f)};
-
- /* Draw a panel and header backdrops with an opaque box backdrop for box style panels. */
- if (draw_box_style && !is_subpanel) {
- /* Expand the top a tiny bit to give header buttons equal size above and below. */
- rcti box_rect = {rect->xmin,
- rect->xmax,
- UI_panel_is_closed(panel) ? headrect.ymin : rect->ymin,
- headrect.ymax + U.pixelsize};
- ui_draw_box_opaque(&box_rect, UI_CNR_ALL);
-
- /* Mimic the border between aligned box widgets for the bottom of the header. */
- if (!UI_panel_is_closed(panel)) {
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(GPU_BLEND_ALPHA);
-
- immUniformColor4ubv(box_wcol->outline);
- immRectf(pos, rect->xmin, headrect.ymin - U.pixelsize, rect->xmax, headrect.ymin);
- uchar emboss_col[4];
- UI_GetThemeColor4ubv(TH_WIDGET_EMBOSS, emboss_col);
- immUniformColor4ubv(emboss_col);
- immRectf(pos,
- rect->xmin,
- headrect.ymin - U.pixelsize,
- rect->xmax,
- headrect.ymin - U.pixelsize - 1);
-
- GPU_blend(GPU_BLEND_NONE);
- immUnbindProgram();
- }
- }
-
- /* Draw the header backdrop. */
- if (show_background && !is_subpanel && !draw_box_style) {
- const float minx = rect->xmin;
- const float y = headrect.ymax;
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(GPU_BLEND_ALPHA);
-
- /* Draw with background color. */
- immUniformThemeColor(UI_panel_matches_search_filter(panel) ? TH_MATCH : TH_PANEL_HEADER);
- immRectf(pos, minx, headrect.ymin, rect->xmax, y);
-
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(pos, minx, y);
- immVertex2f(pos, rect->xmax, y);
-
- immVertex2f(pos, minx, y);
- immVertex2f(pos, rect->xmax, y);
-
- immEnd();
-
- GPU_blend(GPU_BLEND_NONE);
- immUnbindProgram();
- }
+ /* Offset triangle and text to the right for subpanels. */
+ const rcti widget_rect = {
+ .xmin = header_rect->xmin + (is_subpanel ? scaled_unit * 0.7f : 0),
+ .xmax = header_rect->xmax,
+ .ymin = header_rect->ymin,
+ .ymax = header_rect->ymax,
+ };
- /* draw optional pin icon */
- if (show_pin && (block->panel->flag & PNL_PIN)) {
- uchar col_title[4];
- panel_title_color_get(panel, show_background, region_search_filter_active, col_title);
+ uchar title_color[4];
+ panel_title_color_get(panel, show_background, region_search_filter_active, title_color);
+ title_color[3] = 255;
+ /* Draw collapse icon. */
+ {
+ rctf collapse_rect = {
+ .xmin = widget_rect.xmin,
+ .xmax = widget_rect.xmin + header_height,
+ .ymin = widget_rect.ymin,
+ .ymax = widget_rect.ymax,
+ };
+ BLI_rctf_scale(&collapse_rect, 0.25f);
+
+ float triangle_color[4];
+ rgba_uchar_to_float(triangle_color, title_color);
+
+ ui_draw_anti_tria_rect(&collapse_rect, UI_panel_is_closed(panel) ? 'h' : 'v', triangle_color);
+ }
+
+ /* Draw text label. */
+ if (panel->drawname[0] != '\0') {
+ /* + 0.001f to avoid flirting with float inaccuracy .*/
+ const rcti title_rect = {
+ .xmin = widget_rect.xmin + panel->labelofs + scaled_unit * 1.1f,
+ .xmax = widget_rect.xmax,
+ .ymin = widget_rect.ymin - 2.0f / aspect,
+ .ymax = widget_rect.ymax,
+ };
+ UI_fontstyle_draw(fontstyle,
+ &title_rect,
+ panel->drawname,
+ title_color,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_LEFT,
+ });
+ }
+
+ /* Draw the pin icon. */
+ if (show_pin && (panel->flag & PNL_PIN)) {
GPU_blend(GPU_BLEND_ALPHA);
- UI_icon_draw_ex(headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect),
- headrect.ymin + (5.0f / block->aspect),
- (panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED,
- (block->aspect * U.inv_dpi_fac),
+ UI_icon_draw_ex(widget_rect.xmax - scaled_unit * 2.2f,
+ widget_rect.ymin + 5.0f / aspect,
+ ICON_PINNED,
+ aspect * U.inv_dpi_fac,
1.0f,
0.0f,
- col_title,
+ title_color,
false);
GPU_blend(GPU_BLEND_NONE);
}
- /* Draw the title. */
- rcti titlerect = headrect;
- if (is_subpanel) {
- titlerect.xmin += (0.7f * UI_UNIT_X) / block->aspect + 0.001f;
- }
- ui_draw_aligned_panel_header(
- style, block, &titlerect, show_background, region_search_filter_active);
-
- if (show_drag) {
- /* Make `itemrect` smaller. */
- const float scale = 0.7;
- rctf itemrect;
- itemrect.xmax = headrect.xmax - (0.2f * UI_UNIT_X);
- itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
- itemrect.ymin = headrect.ymin;
- itemrect.ymax = headrect.ymax;
- BLI_rctf_scale(&itemrect, scale);
-
+ /* Draw drag widget. */
+ if (!is_subpanel) {
+ const int drag_widget_size = header_height * 0.7f;
GPU_matrix_push();
- GPU_matrix_translate_2f(itemrect.xmin, itemrect.ymin);
+ /* The magic numbers here center the widget vertically and offset it to the left.
+ * Currently this depends on the height of the header, although it could be independent. */
+ GPU_matrix_translate_2f(widget_rect.xmax - scaled_unit * 1.15,
+ widget_rect.ymin + (header_height - drag_widget_size) * 0.5f);
const int col_tint = 84;
- float col_high[4], col_dark[4];
- UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, col_high);
- UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark);
+ float color_high[4], color_dark[4];
+ UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, color_high);
+ UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, color_dark);
GPUBatch *batch = GPU_batch_preset_panel_drag_widget(
- U.pixelsize, col_high, col_dark, BLI_rcti_size_y(&headrect) * scale);
+ U.pixelsize, color_high, color_dark, drag_widget_size);
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_FLAT_COLOR);
GPU_batch_draw(batch);
GPU_matrix_pop();
}
+}
- /* Draw panel backdrop. */
- if (!UI_panel_is_closed(panel)) {
- /* in some occasions, draw a border */
- if (panel->flag & PNL_SELECT && !is_subpanel) {
- float radius;
- if (draw_box_style) {
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- radius = box_wcol->roundness * U.widget_unit;
+static void panel_draw_aligned_backdrop(const Panel *panel,
+ const rcti *rect,
+ const rcti *header_rect)
+{
+ const bool draw_box_style = panel->type->flag & PANEL_TYPE_DRAW_BOX;
+ const bool is_subpanel = panel->type->parent != NULL;
+ const bool is_open = !UI_panel_is_closed(panel);
+
+ const uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ /* Draw with an opaque box backdrop for box style panels. */
+ if (draw_box_style) {
+ /* Use the theme for box widgets. */
+ const uiWidgetColors *box_wcol = &UI_GetTheme()->tui.wcol_box;
+
+ if (is_subpanel) {
+ /* Use rounded bottom corners for the last subpanel. */
+ if (panel->next == NULL) {
+ UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+ float color[4];
+ UI_GetThemeColor4fv(TH_PANEL_SUB_BACK, color);
+ /* Change the width a little bit to line up with sides. */
+ UI_draw_roundbox_aa(true,
+ rect->xmin + U.pixelsize,
+ rect->ymin + U.pixelsize,
+ rect->xmax - U.pixelsize,
+ rect->ymax,
+ box_wcol->roundness * U.widget_unit,
+ color);
}
else {
- UI_draw_roundbox_corner_set(UI_CNR_NONE);
- radius = 0.0f;
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_PANEL_SUB_BACK);
+ immRectf(pos, rect->xmin + U.pixelsize, rect->ymin, rect->xmax - U.pixelsize, rect->ymax);
+ immUnbindProgram();
}
-
- UI_GetThemeColorShade4fv(TH_BACK, -120, color);
- UI_draw_roundbox_aa(false,
- 0.5f + rect->xmin,
- 0.5f + rect->ymin,
- 0.5f + rect->xmax,
- 0.5f + headrect.ymax + 1,
- radius,
- color);
}
-
+ else {
+ /* Expand the top a tiny bit to give header buttons equal size above and below. */
+ rcti box_rect = {
+ .xmin = rect->xmin,
+ .xmax = rect->xmax,
+ .ymin = is_open ? rect->ymin : header_rect->ymin,
+ .ymax = header_rect->ymax + U.pixelsize,
+ };
+ ui_draw_box_opaque(&box_rect, UI_CNR_ALL);
+
+ /* Mimic the border between aligned box widgets for the bottom of the header. */
+ if (is_open) {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_blend(GPU_BLEND_ALPHA);
+
+ /* Top line. */
+ immUniformColor4ubv(box_wcol->outline);
+ immRectf(pos, rect->xmin, header_rect->ymin - U.pixelsize, rect->xmax, header_rect->ymin);
+
+ /* Bottom "shadow" line. */
+ immUniformThemeColor(TH_WIDGET_EMBOSS);
+ immRectf(pos,
+ rect->xmin,
+ header_rect->ymin - U.pixelsize,
+ rect->xmax,
+ header_rect->ymin - U.pixelsize - 1);
+
+ GPU_blend(GPU_BLEND_NONE);
+ immUnbindProgram();
+ }
+ }
+ }
+ else {
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_blend(GPU_BLEND_ALPHA);
- /* Draw panel backdrop if it wasn't already been drawn by the single opaque round box earlier.
- * Note: Sub-panels blend with panels, so they can't be opaque. */
- if (show_background && !(draw_box_style && !is_subpanel)) {
- /* Draw the bottom sub-panels. */
- if (draw_box_style) {
- if (panel->next) {
- immUniformThemeColor(panel_col);
- immRectf(
- pos, rect->xmin + U.pixelsize, rect->ymin, rect->xmax - U.pixelsize, rect->ymax);
- }
- else {
- /* Change the width a little bit to line up with sides. */
- UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
- UI_GetThemeColor4fv(panel_col, color);
- UI_draw_roundbox_aa(true,
- rect->xmin + U.pixelsize,
- rect->ymin + U.pixelsize,
- rect->xmax - U.pixelsize,
- rect->ymax,
- box_wcol->roundness * U.widget_unit,
- color);
- }
- }
- else {
- immUniformThemeColor(panel_col);
- immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- }
+ /* Panel backdrop. */
+ if (is_open || panel->type->flag & PANEL_TYPE_NO_HEADER) {
+ immUniformThemeColor(is_subpanel ? TH_PANEL_SUB_BACK : TH_PANEL_BACK);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
}
+ /* Panel header backdrops for non sub-panels. */
+ if (!is_subpanel) {
+ immUniformThemeColor(UI_panel_matches_search_filter(panel) ? TH_MATCH : TH_PANEL_HEADER);
+ immRectf(pos, rect->xmin, header_rect->ymin, rect->xmax, header_rect->ymax);
+ }
+
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
+}
- /* Draw collapse icon. */
- {
- rctf itemrect = {.xmin = titlerect.xmin,
- .xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect),
- .ymin = titlerect.ymin,
- .ymax = titlerect.ymax};
- BLI_rctf_scale(&itemrect, 0.25f);
-
- uchar col_title[4];
- panel_title_color_get(panel, show_background, region_search_filter_active, col_title);
- float tria_color[4];
- rgb_uchar_to_float(tria_color, col_title);
- tria_color[3] = 1.0f;
+/**
+ * Draw a panel integrated in buttons-window, tool/property lists etc.
+ */
+void ui_draw_aligned_panel(const uiStyle *style,
+ const uiBlock *block,
+ const rcti *rect,
+ const bool show_pin,
+ const bool show_background,
+ const bool region_search_filter_active)
+{
+ const Panel *panel = block->panel;
- if (UI_panel_is_closed(panel)) {
- ui_draw_anti_tria_rect(&itemrect, 'h', tria_color);
- }
- else {
- ui_draw_anti_tria_rect(&itemrect, 'v', tria_color);
- }
+ /* Add 0.001f to prevent flicker frpm float inaccuracy. */
+ const rcti header_rect = {
+ rect->xmin,
+ rect->xmax,
+ rect->ymax,
+ rect->ymax + floor(PNL_HEADER / block->aspect + 0.001f),
+ };
+
+ if (show_background) {
+ panel_draw_aligned_backdrop(panel, rect, &header_rect);
+ }
+
+ /* Draw the widgets and text in the panel header. */
+ if (!(panel->type->flag & PANEL_TYPE_NO_HEADER)) {
+ panel_draw_aligned_widgets(style,
+ panel,
+ &header_rect,
+ block->aspect,
+ show_pin,
+ show_background,
+ region_search_filter_active);
}
}