[Bf-blender-cvs] [ac943796d4d] modifier-panels-ui: Draw list panels with box widget colors and code

Hans Goudey noreply at git.blender.org
Fri Apr 17 00:04:29 CEST 2020


Commit: ac943796d4daad3b3016bdf070798cb51c1edb08
Author: Hans Goudey
Date:   Thu Apr 16 17:04:22 2020 -0500
Branches: modifier-panels-ui
https://developer.blender.org/rBac943796d4daad3b3016bdf070798cb51c1edb08

Draw list panels with box widget colors and code

This solves the transparency and theming issues by reusing the theming
from the box widget. This requires a new drawing function in order to
use box drawing with an opaque inner color, alpha blended with the
region's background color.

===================================================================

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/interface/interface_widgets.c

===================================================================

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index a907da8e47d..6e93dd30f51 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -240,7 +240,6 @@ enum {
 #define UI_PANEL_CATEGORY_MARGIN_WIDTH (U.widget_unit * 1.0f)
 
 #define UI_LIST_PANEL_MARGIN (U.widget_unit * 0.15f)
-#define UI_LIST_PANEL_ROUNDNESS (U.widget_unit * 0.3f)
 
 /* but->drawflag - these flags should only affect how the button is drawn. */
 /* Note: currently, these flags _are not passed_ to the widget's state() or draw() functions
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 6a489b49e20..817fe757e6e 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -841,6 +841,7 @@ struct GPUBatch *ui_batch_roundbox_shadow_get(void);
 
 void ui_draw_anti_tria_rect(const rctf *rect, char dir, const float color[4]);
 void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
+void ui_draw_box_opaque(rcti *rect, int roundboxalign);
 void ui_draw_popover_back(ARegion *region, struct uiStyle *style, uiBlock *block, rcti *rect);
 void ui_draw_pie_center(uiBlock *block);
 const struct uiWidgetColors *ui_tooltip_get_theme(void);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index e0e42df9481..aaf60adcd84 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -848,7 +848,16 @@ void ui_draw_aligned_panel(uiStyle *style,
                            * 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 is_list_panel = (panel->type && panel->type->flag & (PNL_LIST | PNL_LIST_SUBPANEL));
+  float list_panel_roundness = 0.0f;
+
+  /* For list panels, use roundness from the theme for box widgets. */
+  if (is_list_panel) {
+    bTheme *btheme = UI_GetTheme();
+    uiWidgetColors *wcol = &btheme->tui.wcol_box;
+    list_panel_roundness = wcol->roundness;
+  }
 
   if (panel->type && (panel->type->flag & PNL_NO_HEADER)) {
     if (show_background) {
@@ -884,16 +893,13 @@ void ui_draw_aligned_panel(uiStyle *style,
 
     /* List panels have some roundness and a shaded header color to differentiate them. */
     if (is_list_panel) {
-      /* Round all corners if the panel is closed. */
+      int roundbox_corners = (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
       if (is_closed_y) {
-        UI_draw_roundbox_corner_set(UI_CNR_ALL);
+        roundbox_corners |= (UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
       }
-      else {
-        UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
-      }
-
-      UI_GetThemeColorShadeAlpha4fv(TH_PANEL_HEADER, -30, 125, color);
-      UI_draw_roundbox_aa(true, minx, headrect.ymin, maxx, y, UI_LIST_PANEL_ROUNDNESS, color);
+      /* Increase ymax a bit for even space on the top and bottom of the buttons in the header. */
+      rcti box_rect = {minx, maxx, headrect.ymin, y + U.pixelsize};
+      ui_draw_box_opaque(&box_rect, roundbox_corners);
     }
     else {
       GPU_blend(true);
@@ -992,7 +998,7 @@ void ui_draw_aligned_panel(uiStyle *style,
       }
       else if (is_list_panel) {
         UI_draw_roundbox_corner_set(UI_CNR_ALL);
-        radius = UI_LIST_PANEL_ROUNDNESS;
+        radius = list_panel_roundness * U.widget_unit;
       }
       else {
         UI_draw_roundbox_corner_set(UI_CNR_NONE);
@@ -1014,12 +1020,25 @@ void ui_draw_aligned_panel(uiStyle *style,
     GPU_blend(true);
 
     if (show_background) {
-      /* Round the bottom corners as long as this isn't a subpanel between other subpanels. */
+      /* Draw list panels and their bottom subpanels with rounding. */
       if (is_list_panel && !(is_subpanel && panel->next)) {
-        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, rect->ymin, rect->xmax, rect->ymax, UI_LIST_PANEL_ROUNDNESS, color);
+        /* The subpanel should blend with the panel, so it shouldn't be opaque. */
+        if (is_subpanel) {
+          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,
+                              rect->ymin,
+                              rect->xmax,
+                              rect->ymax,
+                              list_panel_roundness * U.widget_unit,
+                              color);
+        }
+        else {
+          /* Increase ymax a bit to so the top aligns with the header box rect. */
+          rcti box_rect = {rect->xmin, rect->xmax, rect->ymin, rect->ymax + U.pixelsize};
+          ui_draw_box_opaque(&box_rect, UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+        }
       }
       else {
         /* panel backdrop */
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index ca688405e19..af2376276f8 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -4238,7 +4238,7 @@ static void widget_box(
   copy_v3_v3_uchar(old_col, wcol->inner);
 
   /* abuse but->hsv - if it's non-zero, use this color as the box's background */
-  if (but->col[3]) {
+  if (but != NULL && but->col[3]) {
     wcol->inner[0] = but->col[0];
     wcol->inner[1] = but->col[1];
     wcol->inner[2] = but->col[2];
@@ -4988,6 +4988,30 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
   ui_draw_clip_tri(block, rect, wt);
 }
 
+/**
+ * Uses the widget base drawing and colors from from the box widget, but ensures an opaque
+ * inner color.
+ */
+void ui_draw_box_opaque(rcti *rect, int roundboxalign)
+{
+  uiWidgetType *wt = widget_type(UI_WTYPE_BOX);
+
+  /* Alpha blend with the region's background color to force an opaque background. */
+  bTheme *btheme = UI_GetTheme();
+  uiWidgetColors wcol = btheme->tui.wcol_box;
+  float background[4];
+  UI_GetThemeColor4fv(TH_BACK, background);
+  float new_inner[4];
+  rgba_uchar_to_float(new_inner, wcol.inner);
+  new_inner[0] = (new_inner[0] * new_inner[3]) + (background[0] * (1.0f - new_inner[3]));
+  new_inner[1] = (new_inner[1] * new_inner[3]) + (background[1] * (1.0f - new_inner[3]));
+  new_inner[2] = (new_inner[2] * new_inner[3]) + (background[2] * (1.0f - new_inner[3]));
+  new_inner[3] = 1.0f;
+  rgba_float_to_uchar(wcol.inner, new_inner);
+
+  wt->custom(NULL, &wcol, rect, 0, roundboxalign);
+}
+
 /**
  * Similar to 'widget_menu_back', however we can't use the widget preset system
  * because we need to pass in the original location so we know where to show the arrow.



More information about the Bf-blender-cvs mailing list