[Bf-blender-cvs] [84825e4ed2e] master: UI: Icon number indicator for data-blocks

Dalai Felinto noreply at git.blender.org
Thu Oct 20 16:50:21 CEST 2022


Commit: 84825e4ed2e098954f0c46adee4d65c8c0ba0e99
Author: Dalai Felinto
Date:   Thu Oct 20 16:37:07 2022 +0200
Branches: master
https://developer.blender.org/rB84825e4ed2e098954f0c46adee4d65c8c0ba0e99

UI: Icon number indicator for data-blocks

Adds the possibility of having a little number on top of icons.

At the moment this is used for:
* Outliner
* Node Editor bread-crumb
* Node Group node header

For the outliner there is almost no functional change. It is mostly a refactor
to handle the indicators as part of the icon shader instead of the outliner
draw code. (note that this was already recently changed in a5d3b648e3e2).

The difference is that now we use rounded border rectangle instead of
circles, and we can go up to 999 elements.

So for the outliner this shows the number of collapsed elements of a
certain type (e.g., mesh objects inside a collapsed collection).

For the node editors is being used to show the use count for the data-block.
This is important for the node editor, so users know whether the node-group
they are editing (or are about to edit) is used elsewhere. This is
particularly important when the Node Options are hidden, which is the
default for node groups appended from the asset libraries.

---

Note: This can be easily enabled for ID templates which can then be part
of T84669. It just need to call UI_but_icon_indicator_number_set in the
function template_add_button_search_menu.

---

Special thanks Clément Foucault for the help figuring out the shader,
Julian Eisel for the help navigating the UI code, and Pablo Vazquez for
the collaboration in this design solution.

For images showing the result check the Differential Revision.
Differential Revision: https://developer.blender.org/D16284

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

M	source/blender/blenlib/BLI_string.h
M	source/blender/blenlib/intern/string.c
M	source/blender/blenlib/tests/BLI_string_test.cc
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/include/UI_interface.hh
M	source/blender/editors/include/UI_interface_icons.h
M	source/blender/editors/interface/interface.cc
M	source/blender/editors/interface/interface_context_path.cc
M	source/blender/editors/interface/interface_icons.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/editors/interface/interface_panel.cc
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/space_file/file_draw.c
M	source/blender/editors/space_info/textview.c
M	source/blender/editors/space_node/node_draw.cc
M	source/blender/editors/space_node/node_relationships.cc
M	source/blender/editors/space_outliner/outliner_draw.cc
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_shader_builtin.c
A	source/blender/gpu/shaders/gpu_shader_icon_frag.glsl
A	source/blender/gpu/shaders/gpu_shader_icon_vert.glsl
M	source/blender/gpu/shaders/infos/gpu_interface_info.hh
A	source/blender/gpu/shaders/infos/gpu_shader_icon_info.hh
M	source/blender/windowmanager/intern/wm_dragdrop.cc

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

diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 15926e8f2d2..17abcf52ecc 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -308,6 +308,28 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) A
  * Length of 7 is the maximum of the resulting string, for example, `-15.5K\0`.
  */
 void BLI_str_format_decimal_unit(char dst[7], int number_to_format) ATTR_NONNULL();
+/**
+ * Format a count to up to 3 places (plus minus sign, plus '\0' terminator) string using long
+ * number names abbreviations. Used to produce a compact representation of large numbers as
+ * integers.
+ *
+ * It shows a lower bound instead of rounding the number.
+ *
+ * 1 -> 1
+ * 15 -> 15
+ * 155 -> 155
+ * 1555 -> 1K
+ * 15555 -> 15K
+ * 155555 -> .1M
+ * 1555555 -> 1M
+ * 15555555 -> 15M
+ * 155555555 -> .1B
+ * 1000000000 -> 1B
+ * ...
+ *
+ * Length of 5 is the maximum of the resulting string, for example, `-15K\0`.
+ */
+void BLI_str_format_integer_unit(char dst[5], int number_to_format) ATTR_NONNULL();
 /**
  * Compare two strings without regard to case.
  *
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 89d31c5e93f..755d2dbd55d 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -1176,4 +1176,34 @@ void BLI_str_format_decimal_unit(char dst[7], int number_to_format)
   BLI_snprintf(dst, dst_len, "%.*f%s", decimals, number_to_format_converted, units[order]);
 }
 
+void BLI_str_format_integer_unit(char dst[5], const int number_to_format)
+{
+  float number_to_format_converted = number_to_format;
+  int order = 0;
+  const float base = 1000;
+  const char *units[] = {"", "K", "M", "B"};
+  const int units_num = ARRAY_SIZE(units);
+
+  while ((fabsf(number_to_format_converted) >= base) && ((order + 1) < units_num)) {
+    number_to_format_converted /= base;
+    order++;
+  }
+
+  const bool add_dot = (abs(number_to_format) > 99999) && fabsf(number_to_format_converted) > 99;
+
+  if (add_dot) {
+    number_to_format_converted /= 100;
+    order++;
+  }
+
+  const size_t dst_len = 5;
+  BLI_snprintf(dst,
+               dst_len,
+               "%s%s%d%s",
+               number_to_format < 0 ? "-" : "",
+               add_dot ? "." : "",
+               (int)floorf(fabsf(number_to_format_converted)),
+               units[order]);
+}
+
 /** \} */
diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc
index 9bdf6075c70..d726fbccf20 100644
--- a/source/blender/blenlib/tests/BLI_string_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_test.cc
@@ -515,6 +515,103 @@ TEST(string, StrFormatDecimalUnits)
   EXPECT_STREQ("-2.1B", size_str);
 }
 
+/* BLI_str_format_integer_unit */
+TEST(string, StrFormatIntegerUnits)
+{
+  char size_str[7];
+  int size;
+
+  BLI_str_format_integer_unit(size_str, size = 0);
+  EXPECT_STREQ("0", size_str);
+  BLI_str_format_integer_unit(size_str, size = 1);
+  EXPECT_STREQ("1", size_str);
+  BLI_str_format_integer_unit(size_str, size = 10);
+  EXPECT_STREQ("10", size_str);
+  BLI_str_format_integer_unit(size_str, size = 15);
+  EXPECT_STREQ("15", size_str);
+  BLI_str_format_integer_unit(size_str, size = 100);
+  EXPECT_STREQ("100", size_str);
+  BLI_str_format_integer_unit(size_str, size = 155);
+  EXPECT_STREQ("155", size_str);
+  BLI_str_format_integer_unit(size_str, size = 1000);
+  EXPECT_STREQ("1K", size_str);
+  BLI_str_format_integer_unit(size_str, size = 1555);
+  EXPECT_STREQ("1K", size_str);
+  BLI_str_format_integer_unit(size_str, size = 10000);
+  EXPECT_STREQ("10K", size_str);
+  BLI_str_format_integer_unit(size_str, size = 15555);
+  EXPECT_STREQ("15K", size_str);
+  BLI_str_format_integer_unit(size_str, size = 100000);
+  EXPECT_STREQ(".1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = 155555);
+  EXPECT_STREQ(".1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = 1000000);
+  EXPECT_STREQ("1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = 1555555);
+  EXPECT_STREQ("1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = 2555555);
+  EXPECT_STREQ("2M", size_str);
+  BLI_str_format_integer_unit(size_str, size = 10000000);
+  EXPECT_STREQ("10M", size_str);
+  BLI_str_format_integer_unit(size_str, size = 15555555);
+  EXPECT_STREQ("15M", size_str);
+  BLI_str_format_integer_unit(size_str, size = 100000000);
+  EXPECT_STREQ(".1B", size_str);
+  BLI_str_format_integer_unit(size_str, size = 155555555);
+  EXPECT_STREQ(".1B", size_str);
+  BLI_str_format_integer_unit(size_str, size = 255555555);
+  EXPECT_STREQ(".2B", size_str);
+  BLI_str_format_integer_unit(size_str, size = 1000000000);
+  EXPECT_STREQ("1B", size_str);
+
+  /* Largest possible value. */
+  BLI_str_format_integer_unit(size_str, size = INT32_MAX);
+  EXPECT_STREQ("2B", size_str);
+
+  BLI_str_format_integer_unit(size_str, size = -0);
+  EXPECT_STREQ("0", size_str);
+  BLI_str_format_integer_unit(size_str, size = -1);
+  EXPECT_STREQ("-1", size_str);
+  BLI_str_format_integer_unit(size_str, size = -10);
+  EXPECT_STREQ("-10", size_str);
+  BLI_str_format_integer_unit(size_str, size = -15);
+  EXPECT_STREQ("-15", size_str);
+  BLI_str_format_integer_unit(size_str, size = -100);
+  EXPECT_STREQ("-100", size_str);
+  BLI_str_format_integer_unit(size_str, size = -155);
+  EXPECT_STREQ("-155", size_str);
+  BLI_str_format_integer_unit(size_str, size = -1000);
+  EXPECT_STREQ("-1K", size_str);
+  BLI_str_format_integer_unit(size_str, size = -1555);
+  EXPECT_STREQ("-1K", size_str);
+  BLI_str_format_integer_unit(size_str, size = -10000);
+  EXPECT_STREQ("-10K", size_str);
+  BLI_str_format_integer_unit(size_str, size = -15555);
+  EXPECT_STREQ("-15K", size_str);
+  BLI_str_format_integer_unit(size_str, size = -100000);
+  EXPECT_STREQ("-.1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = -155555);
+  EXPECT_STREQ("-.1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = -1000000);
+  EXPECT_STREQ("-1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = -1555555);
+  EXPECT_STREQ("-1M", size_str);
+  BLI_str_format_integer_unit(size_str, size = -10000000);
+  EXPECT_STREQ("-10M", size_str);
+  BLI_str_format_integer_unit(size_str, size = -15555555);
+  EXPECT_STREQ("-15M", size_str);
+  BLI_str_format_integer_unit(size_str, size = -100000000);
+  EXPECT_STREQ("-.1B", size_str);
+  BLI_str_format_integer_unit(size_str, size = -155555555);
+  EXPECT_STREQ("-.1B", size_str);
+  BLI_str_format_integer_unit(size_str, size = -1000000000);
+  EXPECT_STREQ("-1B", size_str);
+
+  /* Smallest possible value. */
+  BLI_str_format_integer_unit(size_str, size = -INT32_MAX);
+  EXPECT_STREQ("-2B", size_str);
+}
+
 struct WordInfo {
   WordInfo() = default;
   WordInfo(int start, int end) : start(start), end(end)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 2a1941f0d9e..7e9422ff867 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1683,6 +1683,7 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name);
  * Adds a hint to the button which draws right aligned, grayed out and never clipped.
  */
 void UI_but_hint_drawstr_set(uiBut *but, const char *string);
+void UI_but_icon_indicator_number_set(uiBut *but, const int indicator_number);
 
 void UI_but_node_link_set(uiBut *but, struct bNodeSocket *socket, const float draw_color[4]);
 
@@ -2788,7 +2789,8 @@ typedef struct uiPropertySplitWrapper {
 uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout);
 
 void uiItemL(uiLayout *layout, const char *name, int icon); /* label */
-void uiItemL_ex(uiLayout *layout, const char *name, int icon, bool highlight, bool redalert);
+struct uiBut *uiItemL_ex(
+    uiLayout *layout, const char *name, int icon, bool highlight, bool redalert);
 /**
  * Helper to add a label and creates a property split layout if needed.
  */
diff --git a/source/blender/editors/include/UI_interface.hh b/source/blender/editors/include/UI_interface.hh
index 6c756984203..fc03b0218c0 100644
--- a/source/blender/editors/include/UI_interface.hh
+++ b/source/blender/editors/include/UI_interface.hh
@@ -35,6 +35,7 @@ struct ContextPathItem {
   std::string name;
   /* #BIFIconID */
   int icon;
+  int icon_indicator_number;
 };
 
 void context_path_add_generic(Vector<ContextPathItem> &path,
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index a1a98a4b08c..9669e242dac 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -27,6 +27,12 @@ typedef struct IconFile {
   int index;
 } IconFile;
 
+typedef struct IconTextOverlay {
+  char text[5];
+} IconTextOverlay;
+
+#define UI_NO_ICON_OVERLAY_TEXT NULL
+
 #define ICON_DEFAULT_HEIGHT 16
 #define ICON_DEFAULT_WIDTH 16
 
@@ -105,7 +111,8 @@ void UI_icon_draw_ex(float x,
                      float alpha,
                      float desaturate,
                      const uchar mono_color[4],
-                     bool mono_border);
+                     bool mono_border,
+                     const struct IconTextOverlay *text_overlay);
 
 void UI_icons_free(void);
 void UI_icons_free_drawinfo(void *drawinfo);
@@ -124,6 +131,9 @@ int UI_icon_from_library(const struct ID *id);
 int UI_icon_from_object_mode(int mode);
 int UI_icon_color_from_collection(const struct Collection *collection);
 
+void UI_icon_text_overlay_init_from_count(struct IconTextOverlay *text_overlay,
+                                          const int icon_indicator_number);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc
index 422fc34aa50..1f88d25af2b 100644
--- a/source/blender/editors/interface/interface.cc
+++ b/source/blender/editors/interface/interface.cc
@@ -6452,6 +6452,11 @@ void UI_but_hint_drawstr_set(uiBut *but, const char *string)
   ui_but_add_shortcut(but, string, false)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list