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:
authorFabian Schempp <fabianschempp@googlemail.com>2021-06-25 08:57:24 +0300
committerFabian Schempp <fabianschempp@googlemail.com>2021-06-25 08:57:24 +0300
commitae085e301c2aac0d6956609bfe93a90a19f0e235 (patch)
tree38b86749807915a6b6d46504a2acb90e41a4a77a
parent841df831e89dfc4011c323203c2efb8265dc1878 (diff)
Spreadsheet: Dataset region for spreadsheet editor
This patch adds a left aligned sidebar to the spreadsheet editor. This Sidebar can be used to navigate the geometry component types and attribute domains. It also provides a quick overview of domain sizes. It replaces the two dropdowns in the regions header. Next step will be to add the domain cycling shortcut using the CTRL + mouse wheel. Reviewer: Dalai Felinto (dfelinto), Julian Eisel (Severin), Hans Goudey (HooglyBoogly). Differential Revision: https://developer.blender.org/D11046
-rw-r--r--release/datafiles/userdef/userdef_default_theme.c5
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py9
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py15
-rw-r--r--release/scripts/startup/bl_ui/space_spreadsheet.py4
-rw-r--r--source/blender/blenkernel/BKE_attribute.h8
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenlib/BLI_string.h2
-rw-r--r--source/blender/blenlib/intern/string.c38
-rw-r--r--source/blender/blenlib/tests/BLI_string_test.cc95
-rw-r--r--source/blender/blenloader/intern/versioning_300.c23
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c9
-rw-r--r--source/blender/editors/include/ED_spreadsheet.h4
-rw-r--r--source/blender/editors/include/UI_interface.h12
-rw-r--r--source/blender/editors/interface/interface.c65
-rw-r--r--source/blender/editors/interface/interface_handlers.c15
-rw-r--r--source/blender/editors/interface/interface_intern.h11
-rw-r--r--source/blender/editors/interface/interface_query.c3
-rw-r--r--source/blender/editors/interface/interface_widgets.c32
-rw-r--r--source/blender/editors/space_spreadsheet/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc109
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_context.cc4
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc9
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc277
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh64
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc112
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh68
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_intern.hh13
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_ops.cc53
-rw-r--r--source/blender/makesrna/intern/rna_space.c23
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c1
30 files changed, 1045 insertions, 44 deletions
diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c
index 48e675492f9..441a92127ea 100644
--- a/release/datafiles/userdef/userdef_default_theme.c
+++ b/release/datafiles/userdef/userdef_default_theme.c
@@ -1041,6 +1041,11 @@ const bTheme U_theme_default = {
.active_object = RGBA(0xffaf29ff),
.edited_object = RGBA(0x00806266),
.row_alternate = RGBA(0xffffff07),
+ .list = RGBA(0x424242ff),
+ .list_title = RGBA(0xc3c3c3ff),
+ .list_text = RGBA(0xc3c3c3ff),
+ .list_text_hi = RGBA(0xffffff),
+ .hilite = RGBA(0x80808080),
},
.tarm = {
{
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index bd14b2c532c..7f1039a975b 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -187,7 +187,7 @@ def _template_items_context_panel(menu, key_args_primary):
]
-def _template_space_region_type_toggle(*, toolbar_key=None, sidebar_key=None):
+def _template_space_region_type_toggle(*, toolbar_key=None, sidebar_key=None, channels_key=None):
items = []
if toolbar_key is not None:
items.append(
@@ -199,6 +199,12 @@ def _template_space_region_type_toggle(*, toolbar_key=None, sidebar_key=None):
("wm.context_toggle", sidebar_key,
{"properties": [("data_path", 'space_data.show_region_ui')]}),
)
+ if channels_key is not None:
+ items.append(
+ ("wm.context_toggle", channels_key,
+ {"properties": [("data_path", 'space_data.show_region_channels')]}),
+ )
+
return items
@@ -3021,6 +3027,7 @@ def km_spreadsheet_generic(_params):
items.extend([
*_template_space_region_type_toggle(
sidebar_key={"type": 'N', "value": 'PRESS'},
+ channels_key={"type": 'T', "value": 'PRESS'},
),
])
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index e56783fcc21..b0144672745 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -2143,6 +2143,21 @@ def km_clip_dopesheet_editor(_params):
return keymap
+def km_spreadsheet_generic(_params):
+ items = []
+ keymap = (
+ "Spreadsheet Generic",
+ {"space_type": 'SPREADSHEET', "region_type": 'WINDOW'},
+ {"items": items},
+ )
+
+ items.extend([
+ *_template_space_region_type_toggle(
+ channels_key={"type": 'T', "value": 'PRESS'},
+ ),
+ ])
+
+ return keymap
# ------------------------------------------------------------------------------
# Animation
diff --git a/release/scripts/startup/bl_ui/space_spreadsheet.py b/release/scripts/startup/bl_ui/space_spreadsheet.py
index 360849a0c7a..178be9ef0b7 100644
--- a/release/scripts/startup/bl_ui/space_spreadsheet.py
+++ b/release/scripts/startup/bl_ui/space_spreadsheet.py
@@ -41,10 +41,6 @@ class SPREADSHEET_HT_header(bpy.types.Header):
return
layout.prop(space, "object_eval_state", text="")
- if space.object_eval_state != 'ORIGINAL':
- layout.prop(space, "geometry_component_type", text="")
- if space.geometry_component_type != 'INSTANCES':
- layout.prop(space, "attribute_domain", text="")
context_path = space.context_path
if space.object_eval_state == 'ORIGINAL':
diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
index 30a595dba8e..6a1f1feb14f 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -38,12 +38,16 @@ struct ID;
struct ReportList;
/* Attribute.domain */
+/**
+ * \warning: Careful when changing existing items. Arrays may be initialized from this (e.g.
+ * #DATASET_layout_hierarchy).
+ */
typedef enum AttributeDomain {
ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */
ATTR_DOMAIN_POINT = 0, /* Mesh, Hair or PointCloud Point */
ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */
- ATTR_DOMAIN_CORNER = 2, /* Mesh Corner */
- ATTR_DOMAIN_FACE = 3, /* Mesh Face */
+ ATTR_DOMAIN_FACE = 2, /* Mesh Face */
+ ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */
ATTR_DOMAIN_CURVE = 4, /* Hair Curve */
ATTR_DOMAIN_NUM
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 1767077fa45..bac982708bc 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 4
+#define BLENDER_FILE_SUBVERSION 5
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 5a80680c350..f4a417dbe65 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -100,7 +100,7 @@ size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL();
size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) ATTR_NONNULL();
void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10)
ATTR_NONNULL();
-
+void BLI_str_format_attribute_domain_size(char dst[4], int number_to_format) ATTR_NONNULL();
int BLI_strcaseeq(const char *a, const char *b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
char *BLI_strcasestr(const char *s, const char *find) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
char *BLI_strncasestr(const char *s, const char *find, size_t len) ATTR_WARN_UNUSED_RESULT
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 3d40c6ef146..cadee2bfe12 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -1230,6 +1230,44 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base
}
/**
+ * Format a attribute domain to a up to 6 places (plus '\0' terminator) string using long number names abbreviations.
+ * This function is designed to produce a compact representation of large numbers.
+ * 1 -> 1
+ * 15 -> 15
+ * 155 -> 155
+ * 1555 -> 1.6K
+ * 15555 -> 15.6K
+ * 155555 -> 156K
+ * 1555555 -> 1.6M
+ * 15555555 -> 15.6M
+ * 155555555 -> 156M
+ * 1000000000 -> 1B
+ * ...
+ * Dimension of 7 is the maximum length of the resulting string
+ * A combination with 7 places would be -15.5K\0
+ */
+void BLI_str_format_attribute_domain_size(char dst[7], 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 tot_units = ARRAY_SIZE(units);
+
+ while ((fabsf(number_to_format_converted) >= base) && ((order + 1) < tot_units)) {
+ number_to_format_converted /= base;
+ order++;
+ }
+
+ const size_t dst_len = 7;
+ int decimals = 0;
+ if ((order > 0) && fabsf(number_to_format_converted) < 100.0f) {
+ decimals = 1;
+ }
+ BLI_snprintf(dst, dst_len, "%.*f%s", decimals, number_to_format_converted, units[order]);
+}
+
+/**
* Find the ranges needed to split \a str into its individual words.
*
* \param str: The string to search for words.
diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc
index 0b68ee8b93c..ccd2d01be98 100644
--- a/source/blender/blenlib/tests/BLI_string_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_test.cc
@@ -420,6 +420,101 @@ TEST(string, StrFormatByteUnits)
EXPECT_STREQ("-8191.8472 PiB", size_str);
}
+/* BLI_str_format_attribute_domain_size */
+TEST(string, StrFormatAttributeDomainSize)
+{
+ char size_str[7];
+ int size;
+
+ BLI_str_format_attribute_domain_size(size_str, size = 0);
+ EXPECT_STREQ("0", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 1);
+ EXPECT_STREQ("1", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 10);
+ EXPECT_STREQ("10", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 15);
+ EXPECT_STREQ("15", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 100);
+ EXPECT_STREQ("100", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 155);
+ EXPECT_STREQ("155", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 1000);
+ EXPECT_STREQ("1.0K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 1555);
+ EXPECT_STREQ("1.6K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 10000);
+ EXPECT_STREQ("10.0K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 15555);
+ EXPECT_STREQ("15.6K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 100000);
+ EXPECT_STREQ("100K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 100000);
+ EXPECT_STREQ("100K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 155555);
+ EXPECT_STREQ("156K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 1000000);
+ EXPECT_STREQ("1.0M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 1555555);
+ EXPECT_STREQ("1.6M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 10000000);
+ EXPECT_STREQ("10.0M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 15555555);
+ EXPECT_STREQ("15.6M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 100000000);
+ EXPECT_STREQ("100M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 155555555);
+ EXPECT_STREQ("156M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = 1000000000);
+ EXPECT_STREQ("1.0B", size_str);
+
+ /* Largest possible value. */
+ BLI_str_format_attribute_domain_size(size_str, size = INT32_MAX);
+ EXPECT_STREQ("2.1B", size_str);
+
+ BLI_str_format_attribute_domain_size(size_str, size = -0);
+ EXPECT_STREQ("0", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -1);
+ EXPECT_STREQ("-1", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -10);
+ EXPECT_STREQ("-10", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -15);
+ EXPECT_STREQ("-15", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -100);
+ EXPECT_STREQ("-100", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -155);
+ EXPECT_STREQ("-155", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -1000);
+ EXPECT_STREQ("-1.0K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -1555);
+ EXPECT_STREQ("-1.6K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -10000);
+ EXPECT_STREQ("-10.0K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -15555);
+ EXPECT_STREQ("-15.6K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -100000);
+ EXPECT_STREQ("-100K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -155555);
+ EXPECT_STREQ("-156K", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -1000000);
+ EXPECT_STREQ("-1.0M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -1555555);
+ EXPECT_STREQ("-1.6M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -10000000);
+ EXPECT_STREQ("-10.0M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -15555555);
+ EXPECT_STREQ("-15.6M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -100000000);
+ EXPECT_STREQ("-100M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -155555555);
+ EXPECT_STREQ("-156M", size_str);
+ BLI_str_format_attribute_domain_size(size_str, size = -1000000000);
+ EXPECT_STREQ("-1.0B", size_str);
+
+ /* Smallest possible value. */
+ BLI_str_format_attribute_domain_size(size_str, size = -INT32_MAX);
+ EXPECT_STREQ("-2.1B", size_str);
+}
+
struct WordInfo {
WordInfo() = default;
WordInfo(int start, int end) : start(start), end(end)
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 0fe1267b871..cb0f1f29bff 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -40,7 +40,9 @@
#include "BKE_node.h"
#include "BLO_readfile.h"
+#include "MEM_guardedalloc.h"
#include "readfile.h"
+#include "versioning_common.h"
#include "MEM_guardedalloc.h"
@@ -122,6 +124,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
sort_linked_ids(bmain);
assert_sorted_ids(bmain);
}
+
if (MAIN_VERSION_ATLEAST(bmain, 300, 3)) {
assert_sorted_ids(bmain);
}
@@ -392,6 +395,26 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 5)) {
+ /* Add a dataset sidebar to the spreadsheet editor. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_SPREADSHEET) {
+ ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
+ &sl->regionbase;
+ ARegion *spreadsheet_dataset_region = do_versions_add_region_if_not_found(
+ regionbase, RGN_TYPE_CHANNELS, "spreadsheet dataset region", RGN_TYPE_FOOTER);
+
+ if (spreadsheet_dataset_region) {
+ spreadsheet_dataset_region->alignment = RGN_ALIGN_LEFT;
+ spreadsheet_dataset_region->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ }
+ }
+ }
+ }
+ }
+ }
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index be3834faa5a..42b27f57e2c 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -277,6 +277,15 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
btheme->space_spreadsheet = btheme->space_outliner;
}
+ if (!USER_VERSION_ATLEAST(300, 5)) {
+ FROM_DEFAULT_V4_UCHAR(space_spreadsheet.active);
+ FROM_DEFAULT_V4_UCHAR(space_spreadsheet.list);
+ FROM_DEFAULT_V4_UCHAR(space_spreadsheet.list_text);
+ FROM_DEFAULT_V4_UCHAR(space_spreadsheet.list_text_hi);
+ FROM_DEFAULT_V4_UCHAR(space_spreadsheet.hilite);
+ FROM_DEFAULT_V4_UCHAR(space_spreadsheet.selected_highlight);
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/editors/include/ED_spreadsheet.h b/source/blender/editors/include/ED_spreadsheet.h
index 3a07b1b9d4b..88bc4738c0b 100644
--- a/source/blender/editors/include/ED_spreadsheet.h
+++ b/source/blender/editors/include/ED_spreadsheet.h
@@ -30,9 +30,9 @@ struct SpreadsheetContext *ED_spreadsheet_context_new(int type);
void ED_spreadsheet_context_free(struct SpreadsheetContext *context);
void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet);
void ED_spreadsheet_context_path_update_tag(struct SpaceSpreadsheet *sspreadsheet);
-uint64_t ED_spreadsheet_context_path_hash(struct SpaceSpreadsheet *sspreadsheet);
+uint64_t ED_spreadsheet_context_path_hash(const struct SpaceSpreadsheet *sspreadsheet);
-struct ID *ED_spreadsheet_get_current_id(struct SpaceSpreadsheet *sspreadsheet);
+struct ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet);
void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsheet,
struct SpaceNode *snode,
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index df65c602fc4..7553a2d373e 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -386,6 +386,7 @@ typedef enum {
/** Resize handle (resize uilist). */
UI_BTYPE_GRIP = 57 << 9,
UI_BTYPE_DECORATOR = 58 << 9,
+ UI_BTYPE_DATASETROW = 59 << 9,
} eButType;
#define BUTTYPE (63 << 9)
@@ -516,7 +517,7 @@ typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C,
/* Must return allocated string. */
typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip);
-typedef int (*uiButPushedStateFunc)(struct bContext *C, void *arg);
+typedef int (*uiButPushedStateFunc)(struct uiBut *but, const void *arg);
typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
@@ -1612,6 +1613,13 @@ int UI_searchbox_size_x(void);
/* check if a string is in an existing search box */
int UI_search_items_find_index(uiSearchItems *items, const char *name);
+void UI_but_hint_drawstr_set(uiBut *but, const char *string);
+void UI_but_datasetrow_indentation_set(uiBut *but, int indentation);
+void UI_but_datasetrow_component_set(uiBut *but, uint8_t geometry_component_type);
+void UI_but_datasetrow_domain_set(uiBut *but, uint8_t attribute_domain);
+uint8_t UI_but_datasetrow_component_get(uiBut *but);
+uint8_t UI_but_datasetrow_domain_get(uiBut *but);
+
void UI_but_node_link_set(uiBut *but, struct bNodeSocket *socket, const float draw_color[4]);
void UI_but_number_step_size_set(uiBut *but, float step_size);
@@ -1650,7 +1658,7 @@ void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but);
void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN);
-void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, void *arg);
+void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, const void *arg);
struct PointerRNA *UI_but_extra_operator_icon_add(uiBut *but,
const char *opname,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 90639878958..bbc111d91db 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2105,8 +2105,10 @@ void UI_region_message_subscribe(ARegion *region, struct wmMsgBus *mbus)
int ui_but_is_pushed_ex(uiBut *but, double *value)
{
int is_push = 0;
-
- if (but->bit) {
+ if (but->pushed_state_func) {
+ return but->pushed_state_func(but, but->pushed_state_arg);
+ }
+ else if (but->bit) {
const bool state = !ELEM(
but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N);
int lvalue;
@@ -2253,7 +2255,6 @@ void ui_but_v3_get(uiBut *but, float vec[3])
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
const char *cp = (char *)but->poin;
-
vec[0] = ((float)cp[0]) / 255.0f;
vec[1] = ((float)cp[1]) / 255.0f;
vec[2] = ((float)cp[2]) / 255.0f;
@@ -3903,6 +3904,10 @@ static void ui_but_alloc_info(const eButType type,
alloc_size = sizeof(uiButCurveProfile);
alloc_str = "uiButCurveProfile";
break;
+ case UI_BTYPE_DATASETROW:
+ alloc_size = sizeof(uiButDatasetRow);
+ alloc_str = "uiButDatasetRow";
+ break;
default:
alloc_size = sizeof(uiBut);
alloc_str = "uiBut";
@@ -4100,6 +4105,7 @@ static uiBut *ui_def_but(uiBlock *block,
UI_BTYPE_BUT_MENU,
UI_BTYPE_SEARCH_MENU,
UI_BTYPE_PROGRESS_BAR,
+ UI_BTYPE_DATASETROW,
UI_BTYPE_POPOVER)) {
but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
}
@@ -6336,10 +6342,11 @@ void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN)
but->tip_argN = argN;
}
-void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, void *arg)
+void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, const void *arg)
{
but->pushed_state_func = func;
but->pushed_state_arg = arg;
+ ui_but_update(but);
}
uiBut *uiDefBlockBut(uiBlock *block,
@@ -6824,6 +6831,56 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block,
return but;
}
+void UI_but_datasetrow_indentation_set(uiBut *but, int indentation)
+{
+ uiButDatasetRow *but_dataset = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ but_dataset->indentation = indentation;
+ BLI_assert(indentation >= 0);
+
+}
+
+/**
+ * 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)
+{
+ ui_but_add_shortcut(but, string, false);
+}
+
+void UI_but_datasetrow_component_set(uiBut *but, uint8_t geometry_component_type)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ but_dataset_row->geometry_component_type = geometry_component_type;
+}
+
+void UI_but_datasetrow_domain_set(uiBut *but, uint8_t attribute_domain)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ but_dataset_row->attribute_domain = attribute_domain;
+}
+
+uint8_t UI_but_datasetrow_component_get(uiBut *but)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ return but_dataset_row->geometry_component_type;
+}
+
+uint8_t UI_but_datasetrow_domain_get(uiBut *but)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ return but_dataset_row->attribute_domain;
+}
+
void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4])
{
but->flag |= UI_BUT_NODE_LINK;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 34465502c71..7d866ec17d2 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1461,12 +1461,9 @@ static bool ui_drag_toggle_but_is_supported(const uiBut *but)
/* Button pushed state to compare if other buttons match. Can be more
* then just true or false for toggle buttons with more than 2 states. */
-static int ui_drag_toggle_but_pushed_state(bContext *C, uiBut *but)
+static int ui_drag_toggle_but_pushed_state(uiBut *but)
{
if (but->rnapoin.data == NULL && but->poin == NULL && but->icon) {
- if (but->pushed_state_func) {
- return but->pushed_state_func(C, but->pushed_state_arg);
- }
/* Assume icon identifies a unique state, for buttons that
* work through functions callbacks and don't have an boolean
* value that indicates the state. */
@@ -1513,7 +1510,7 @@ static bool ui_drag_toggle_set_xy_xy(
/* execute the button */
if (ui_drag_toggle_but_is_supported(but)) {
/* is it pressed? */
- const int pushed_state_but = ui_drag_toggle_but_pushed_state(C, but);
+ const int pushed_state_but = ui_drag_toggle_but_pushed_state(but);
if (pushed_state_but != pushed_state) {
UI_but_execute(C, region, but);
if (do_check) {
@@ -1943,7 +1940,7 @@ static bool ui_but_drag_init(bContext *C,
* typically 'button_activate_exit()' handles this */
ui_apply_but_autokey(C, but);
- drag_info->pushed_state = ui_drag_toggle_but_pushed_state(C, but);
+ drag_info->pushed_state = ui_drag_toggle_but_pushed_state(but);
drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
copy_v2_v2_int(drag_info->xy_init, &event->x);
@@ -2187,6 +2184,9 @@ static void ui_apply_but(
case UI_BTYPE_LISTROW:
ui_apply_but_ROW(C, block, but, data);
break;
+ case UI_BTYPE_DATASETROW:
+ ui_apply_but_ROW(C, block, but, data);
+ break;
case UI_BTYPE_TAB:
ui_apply_but_TAB(C, but, data);
break;
@@ -7851,6 +7851,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_LABEL:
case UI_BTYPE_IMAGE:
case UI_BTYPE_PROGRESS_BAR:
+ case UI_BTYPE_DATASETROW:
+ retval = ui_do_but_TOG(C, but, data, event);
+ break;
case UI_BTYPE_NODE_SOCKET:
retval = ui_do_but_EXIT(C, but, data, event);
break;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 19ab36cef42..97b9bb66f07 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -279,7 +279,7 @@ struct uiBut {
float *editvec;
uiButPushedStateFunc pushed_state_func;
- void *pushed_state_arg;
+ const void *pushed_state_arg;
/* pointer back */
uiBlock *block;
@@ -350,6 +350,15 @@ typedef struct uiButProgressbar {
float progress;
} uiButProgressbar;
+/** Derived struct for #UI_BTYPE_DATASETROW. */
+typedef struct uiButDatasetRow {
+ uiBut but;
+
+ uint8_t geometry_component_type;
+ uint8_t attribute_domain;
+ int indentation;
+} uiButDatasetRow;
+
/** Derived struct for #UI_BTYPE_HSVCUBE. */
typedef struct uiButHSVCube {
uiBut but;
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index aa10d092f5e..95218e2e7e3 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -67,7 +67,8 @@ bool ui_but_is_toggle(const uiBut *but)
UI_BTYPE_TOGGLE_N,
UI_BTYPE_CHECKBOX,
UI_BTYPE_CHECKBOX_N,
- UI_BTYPE_ROW);
+ UI_BTYPE_ROW,
+ UI_BTYPE_DATASETROW);
}
/**
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 9212a0a7d9d..8badc05065d 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -113,6 +113,7 @@ typedef enum {
UI_WTYPE_LISTITEM,
UI_WTYPE_PROGRESSBAR,
UI_WTYPE_NODESOCKET,
+ UI_WTYPE_DATASETROW,
} uiWidgetTypeEnum;
/* Button state argument shares bits with 'uiBut.flag'.
@@ -3697,6 +3698,28 @@ static void widget_progressbar(
rect->xmax += (BLI_rcti_size_x(&rect_prog) / 2);
}
+static void widget_datasetrow(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
+{
+ uiButDatasetRow *but_componentrow = (uiButDatasetRow *)but;
+ uiWidgetBase wtb;
+ widget_init(&wtb);
+
+ /* no outline */
+ wtb.draw_outline = false;
+ const float rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+
+ if ((state & UI_ACTIVE) || (state & UI_SELECT)) {
+ widgetbase_draw(&wtb, wcol);
+ }
+
+ BLI_rcti_resize(rect,
+ BLI_rcti_size_x(rect) - UI_UNIT_X * but_componentrow->indentation,
+ BLI_rcti_size_y(rect));
+ BLI_rcti_translate(rect, 0.5f * UI_UNIT_X * but_componentrow->indentation, 0);
+}
+
static void widget_nodesocket(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
@@ -4469,6 +4492,10 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
wt.custom = widget_progressbar;
break;
+ case UI_WTYPE_DATASETROW:
+ wt.custom = widget_datasetrow;
+ break;
+
case UI_WTYPE_NODESOCKET:
wt.custom = widget_nodesocket;
break;
@@ -4792,6 +4819,11 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
fstyle = &style->widgetlabel;
break;
+ case UI_BTYPE_DATASETROW:
+ wt = widget_type(UI_WTYPE_DATASETROW);
+ fstyle = &style->widgetlabel;
+ break;
+
case UI_BTYPE_SCROLL:
wt = widget_type(UI_WTYPE_SCROLL);
break;
diff --git a/source/blender/editors/space_spreadsheet/CMakeLists.txt b/source/blender/editors/space_spreadsheet/CMakeLists.txt
index 7e3f3db9bc8..1ea6593588a 100644
--- a/source/blender/editors/space_spreadsheet/CMakeLists.txt
+++ b/source/blender/editors/space_spreadsheet/CMakeLists.txt
@@ -38,6 +38,8 @@ set(SRC
spreadsheet_column.cc
spreadsheet_data_source.cc
spreadsheet_data_source_geometry.cc
+ spreadsheet_dataset_draw.cc
+ spreadsheet_dataset_layout.cc
spreadsheet_draw.cc
spreadsheet_layout.cc
spreadsheet_ops.cc
@@ -50,6 +52,8 @@ set(SRC
spreadsheet_column_values.hh
spreadsheet_data_source.hh
spreadsheet_data_source_geometry.hh
+ spreadsheet_dataset_draw.hh
+ spreadsheet_dataset_layout.hh
spreadsheet_draw.hh
spreadsheet_intern.hh
spreadsheet_layout.hh
diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
index 8c42f28b5f4..f8654500044 100644
--- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
+++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
@@ -47,6 +47,7 @@
#include "spreadsheet_context.hh"
#include "spreadsheet_data_source_geometry.hh"
+#include "spreadsheet_dataset_draw.hh"
#include "spreadsheet_intern.hh"
#include "spreadsheet_layout.hh"
#include "spreadsheet_row_filter.hh"
@@ -80,6 +81,15 @@ static SpaceLink *spreadsheet_create(const ScrArea *UNUSED(area), const Scene *U
}
{
+ /* Dataset Region */
+ ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), "spreadsheet dataset region");
+ BLI_addtail(&spreadsheet_space->regionbase, region);
+ region->regiontype = RGN_TYPE_CHANNELS;
+ region->alignment = RGN_ALIGN_LEFT;
+ region->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ }
+
+ {
/* Properties region. */
ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), "spreadsheet right region");
BLI_addtail(&spreadsheet_space->regionbase, region);
@@ -195,7 +205,7 @@ static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
}
}
-ID *ED_spreadsheet_get_current_id(struct SpaceSpreadsheet *sspreadsheet)
+ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet)
{
if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
return nullptr;
@@ -263,7 +273,7 @@ static void update_context_path_from_context(const bContext *C)
}
}
-static void update_context_path(const bContext *C)
+void spreadsheet_update_context_path(const bContext *C)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
@@ -274,28 +284,40 @@ static void update_context_path(const bContext *C)
}
}
-static std::unique_ptr<DataSource> get_data_source(const bContext *C)
+Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet,
+ const Depsgraph *depsgraph)
{
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
ID *used_id = ED_spreadsheet_get_current_id(sspreadsheet);
if (used_id == nullptr) {
- return {};
+ return nullptr;
}
const ID_Type id_type = GS(used_id->name);
if (id_type != ID_OB) {
- return {};
+ return nullptr;
}
Object *object_orig = (Object *)used_id;
if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME)) {
- return {};
+ return nullptr;
}
+
Object *object_eval = DEG_get_evaluated_object(depsgraph, object_orig);
if (object_eval == nullptr) {
- return {};
+ return nullptr;
}
- return data_source_from_geometry(C, object_eval);
+ return object_eval;
+}
+
+static std::unique_ptr<DataSource> get_data_source(const bContext *C)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+
+ Object *object_eval = spreadsheet_get_object_eval(sspreadsheet, depsgraph);
+ if (object_eval) {
+ return data_source_from_geometry(C, object_eval);
+ }
+ return {};
}
static float get_column_width(const ColumnValues &values)
@@ -358,7 +380,7 @@ static void update_visible_columns(ListBase &columns, DataSource &data_source)
static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- update_context_path(C);
+ spreadsheet_update_context_path(C);
std::unique_ptr<DataSource> data_source = get_data_source(C);
if (!data_source) {
@@ -442,7 +464,7 @@ static void spreadsheet_header_region_init(wmWindowManager *UNUSED(wm), ARegion
static void spreadsheet_header_region_draw(const bContext *C, ARegion *region)
{
- update_context_path(C);
+ spreadsheet_update_context_path(C);
ED_region_header(C, region);
}
@@ -534,6 +556,59 @@ static void spreadsheet_footer_region_listener(const wmRegionListenerParams *UNU
{
}
+static void spreadsheet_dataset_region_listener(const wmRegionListenerParams *params)
+{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
+ switch (wmn->category) {
+ case NC_SCENE: {
+ switch (wmn->data) {
+ case ND_FRAME:
+ ED_region_tag_redraw(region);
+ break;
+ }
+ break;
+ }
+ case NC_TEXTURE:
+ ED_region_tag_redraw(region);
+ break;
+ }
+
+ spreadsheet_header_region_listener(params);
+}
+
+static void spreadsheet_dataset_region_init(wmWindowManager *wm, ARegion *region)
+{
+ region->v2d.scroll |= V2D_SCROLL_RIGHT;
+ region->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP | V2D_SCROLL_BOTTOM);
+ region->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ region->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
+ UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy);
+
+ wmKeyMap *keymap = WM_keymap_ensure(
+ wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
+}
+
+static void spreadsheet_dataset_region_draw(const bContext *C, ARegion *region)
+{
+ spreadsheet_update_context_path(C);
+
+ View2D *v2d = &region->v2d;
+ UI_view2d_view_ortho(v2d);
+ UI_ThemeClearColor(TH_BACK);
+
+ draw_dataset_in_region(C, region);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ UI_view2d_scrollers_draw(v2d, NULL);
+}
+
static void spreadsheet_sidebar_init(wmWindowManager *wm, ARegion *region)
{
UI_panel_category_active_set_default(region, "Filters");
@@ -619,5 +694,15 @@ void ED_spacetype_spreadsheet(void)
register_row_filter_panels(*art);
+ /* regions: channels */
+ art = (ARegionType *)MEM_callocN(sizeof(ARegionType), "spreadsheet dataset region");
+ art->regionid = RGN_TYPE_CHANNELS;
+ art->prefsizex = 200 + V2D_SCROLL_WIDTH;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
+ art->init = spreadsheet_dataset_region_init;
+ art->draw = spreadsheet_dataset_region_draw;
+ art->listener = spreadsheet_dataset_region_listener;
+ BLI_addhead(&st->regiontypes, art);
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
index 3eb43338908..af6ab5d1b92 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
@@ -255,11 +255,11 @@ void ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet)
blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet);
}
-uint64_t ED_spreadsheet_context_path_hash(SpaceSpreadsheet *sspreadsheet)
+uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet)
{
BLI_HashMurmur2A mm2;
BLI_hash_mm2a_init(&mm2, 1234);
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
+ LISTBASE_FOREACH (const SpreadsheetContext *, context, &sspreadsheet->context_path) {
blender::ed::spreadsheet::spreadsheet_context_hash(context, &mm2);
}
return BLI_hash_mm2a_end(&mm2);
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index 0c76c8b7a15..6d244a1bda6 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -385,9 +385,9 @@ int InstancesDataSource::tot_rows() const
return component_->instances_amount();
}
-static GeometrySet get_display_geometry_set(SpaceSpreadsheet *sspreadsheet,
- Object *object_eval,
- const GeometryComponentType used_component_type)
+GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet,
+ Object *object_eval,
+ const GeometryComponentType used_component_type)
{
GeometrySet geometry_set;
if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL) {
@@ -470,7 +470,8 @@ std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
const AttributeDomain domain = (AttributeDomain)sspreadsheet->attribute_domain;
const GeometryComponentType component_type = get_display_component_type(C, object_eval);
- GeometrySet geometry_set = get_display_geometry_set(sspreadsheet, object_eval, component_type);
+ GeometrySet geometry_set = spreadsheet_get_display_geometry_set(
+ sspreadsheet, object_eval, component_type);
if (!geometry_set.has(component_type)) {
return {};
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc
new file mode 100644
index 00000000000..1fa6e47fcdf
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc
@@ -0,0 +1,277 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <array>
+
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+
+#include "BLF_api.h"
+
+#include "BLI_rect.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_view2d.h"
+
+#include "WM_types.h"
+
+#include "spreadsheet_dataset_draw.hh"
+#include "spreadsheet_draw.hh"
+#include "spreadsheet_intern.hh"
+
+static int is_component_row_selected(struct uiBut *but, const void *arg)
+{
+ SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)arg;
+
+ GeometryComponentType component = (GeometryComponentType)UI_but_datasetrow_component_get(but);
+ AttributeDomain domain = (AttributeDomain)UI_but_datasetrow_domain_get(but);
+
+ const bool is_component_selected = (GeometryComponentType)
+ sspreadsheet->geometry_component_type == component;
+ const bool is_domain_selected = (AttributeDomain)sspreadsheet->attribute_domain == domain;
+ bool is_selected = is_component_selected && is_domain_selected;
+
+ if (component == GEO_COMPONENT_TYPE_INSTANCES) {
+ is_selected = is_component_selected;
+ }
+
+ return is_selected;
+}
+
+namespace blender::ed::spreadsheet {
+
+/* -------------------------------------------------------------------- */
+/* Draw Context */
+
+class DatasetDrawContext {
+ std::array<int, 2> mval_;
+
+ public:
+ const SpaceSpreadsheet *sspreadsheet;
+ Object *object_eval;
+ /* Current geometry set, changes per component. */
+ GeometrySet current_geometry_set;
+
+ DatasetDrawContext(const bContext *C);
+
+ GeometrySet geometry_set_from_component(GeometryComponentType component);
+ const std::array<int, 2> &cursor_mval() const;
+};
+
+DatasetDrawContext::DatasetDrawContext(const bContext *C)
+ : sspreadsheet(CTX_wm_space_spreadsheet(C)),
+ object_eval(spreadsheet_get_object_eval(sspreadsheet, CTX_data_depsgraph_pointer(C)))
+{
+ const wmWindow *win = CTX_wm_window(C);
+ const ARegion *region = CTX_wm_region(C);
+ mval_ = {win->eventstate->x - region->winrct.xmin, win->eventstate->y - region->winrct.ymin};
+}
+
+GeometrySet DatasetDrawContext::geometry_set_from_component(GeometryComponentType component)
+{
+ return spreadsheet_get_display_geometry_set(sspreadsheet, object_eval, component);
+}
+
+const std::array<int, 2> &DatasetDrawContext::cursor_mval() const
+{
+ return mval_;
+}
+
+/* -------------------------------------------------------------------- */
+/* Drawer */
+
+DatasetRegionDrawer::DatasetRegionDrawer(const ARegion *region,
+ uiBlock &block,
+ DatasetDrawContext &draw_context)
+ : row_height(UI_UNIT_Y),
+ xmin(region->v2d.cur.xmin),
+ xmax(region->v2d.cur.xmax),
+ block(block),
+ v2d(region->v2d),
+ draw_context(draw_context)
+{
+}
+
+void DatasetRegionDrawer::draw_hierarchy(const DatasetLayoutHierarchy &layout)
+{
+ for (const DatasetComponentLayoutInfo &component : layout.components) {
+ draw_context.current_geometry_set = draw_context.geometry_set_from_component(component.type);
+
+ draw_component_row(component);
+
+ /* Iterate attribute domains, skip unset ones (storage has to be in a enum-based, fixed size
+ * array so uses optionals to support skipping enum values that shouldn't be displayed for a
+ * component). */
+ for (auto &optional_domain : component.attr_domains) {
+ if (!optional_domain) {
+ continue;
+ }
+
+ const DatasetAttrDomainLayoutInfo &domain_info = *optional_domain;
+ draw_attribute_domain_row(component, domain_info);
+ }
+ }
+}
+
+static int element_count_from_component_domain(const GeometrySet &geometry_set,
+ GeometryComponentType component,
+ AttributeDomain domain)
+{
+ if (geometry_set.has_mesh() && component == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent *mesh_component = geometry_set.get_component_for_read<MeshComponent>();
+ return mesh_component->attribute_domain_size(domain);
+ }
+
+ if (geometry_set.has_pointcloud() && component == GEO_COMPONENT_TYPE_POINT_CLOUD) {
+ const PointCloudComponent *point_cloud_component =
+ geometry_set.get_component_for_read<PointCloudComponent>();
+ return point_cloud_component->attribute_domain_size(domain);
+ }
+
+ if (geometry_set.has_instances() && component == GEO_COMPONENT_TYPE_INSTANCES) {
+ const InstancesComponent *instances_component =
+ geometry_set.get_component_for_read<InstancesComponent>();
+ return instances_component->instances_amount();
+ }
+
+ if (geometry_set.has_volume() && component == GEO_COMPONENT_TYPE_VOLUME) {
+ const VolumeComponent *volume_component =
+ geometry_set.get_component_for_read<VolumeComponent>();
+ return volume_component->attribute_domain_size(domain);
+ }
+
+ if (geometry_set.has_curve() && component == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent *curve_component = geometry_set.get_component_for_read<CurveComponent>();
+ return curve_component->attribute_domain_size(domain);
+ }
+
+ return 0;
+}
+
+void DatasetRegionDrawer::draw_dataset_row(const int indentation,
+ const GeometryComponentType component,
+ const std::optional<AttributeDomain> domain,
+ BIFIconID icon,
+ const char *label,
+ const bool is_active)
+{
+
+ const float row_height = UI_UNIT_Y;
+ const float padding_x = UI_UNIT_X * 0.25f;
+
+ const rctf rect = {float(xmin) + padding_x,
+ float(xmax) - V2D_SCROLL_HANDLE_WIDTH,
+ ymin_offset - row_height,
+ ymin_offset};
+
+ char element_count[7];
+ BLI_str_format_attribute_domain_size(
+ element_count,
+ domain ? element_count_from_component_domain(
+ draw_context.current_geometry_set, component, *domain) :
+ 0);
+
+ std::string label_and_element_count = label;
+ label_and_element_count += UI_SEP_CHAR;
+ label_and_element_count += element_count;
+
+ uiBut *bt = uiDefIconTextButO(&block,
+ UI_BTYPE_DATASETROW,
+ "SPREADSHEET_OT_change_spreadsheet_data_source",
+ 0,
+ icon,
+ label,
+ rect.xmin,
+ rect.ymin,
+ BLI_rctf_size_x(&rect),
+ BLI_rctf_size_y(&rect),
+ NULL);
+
+ UI_but_datasetrow_indentation_set(bt, indentation);
+
+ if (is_active) {
+ UI_but_hint_drawstr_set(bt, element_count);
+ UI_but_datasetrow_component_set(bt, component);
+ if (domain) {
+ UI_but_datasetrow_domain_set(bt, *domain);
+ }
+ UI_but_func_pushed_state_set(bt, &is_component_row_selected, draw_context.sspreadsheet);
+
+ PointerRNA *but_ptr = UI_but_operator_ptr_get((uiBut *)bt);
+ RNA_int_set(but_ptr, "component_type", component);
+ if (domain) {
+ RNA_int_set(but_ptr, "attribute_domain_type", *domain);
+ }
+ }
+
+ ymin_offset -= row_height;
+}
+
+void DatasetRegionDrawer::draw_component_row(const DatasetComponentLayoutInfo &component_info)
+{
+ if (component_info.type == GEO_COMPONENT_TYPE_INSTANCES) {
+ draw_dataset_row(
+ 0, component_info.type, std::nullopt, component_info.icon, component_info.label, true);
+ }
+ else {
+ draw_dataset_row(
+ 0, component_info.type, std::nullopt, component_info.icon, component_info.label, false);
+ }
+}
+
+void DatasetRegionDrawer::draw_attribute_domain_row(
+ const DatasetComponentLayoutInfo &component_info,
+ const DatasetAttrDomainLayoutInfo &domain_info)
+{
+ draw_dataset_row(
+ 1, component_info.type, domain_info.type, domain_info.icon, domain_info.label, true);
+}
+
+/* -------------------------------------------------------------------- */
+/* Drawer */
+
+void draw_dataset_in_region(const bContext *C, ARegion *region)
+{
+ DatasetDrawContext draw_context{C};
+ if (!draw_context.object_eval) {
+ /* No object means nothing to display. Keep the region empty. */
+ return;
+ }
+
+ uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
+
+ DatasetRegionDrawer drawer{region, *block, draw_context};
+
+ /* Start with an offset to align buttons to spreadsheet rows. Use spreadsheet drawing info for
+ * that. */
+ drawer.ymin_offset = -SpreadsheetDrawer().top_row_height + drawer.row_height;
+
+ const DatasetLayoutHierarchy hierarchy = dataset_layout_hierarchy();
+ drawer.draw_hierarchy(hierarchy);
+#ifndef NDEBUG
+ dataset_layout_hierarchy_sanity_check(hierarchy);
+#endif
+
+ UI_block_end(C, block);
+ UI_view2d_totRect_set(&region->v2d, region->winx, abs(drawer.ymin_offset));
+ UI_block_draw(C, block);
+}
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh
new file mode 100644
index 00000000000..d9e6d882c2a
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include <array>
+
+#include "BKE_geometry_set.hh"
+#include "UI_interface.h"
+#include "spreadsheet_dataset_layout.hh"
+
+struct ARegion;
+struct uiBlock;
+struct View2D;
+struct bContext;
+
+namespace blender::ed::spreadsheet {
+
+class DatasetDrawContext;
+
+class DatasetRegionDrawer {
+ public:
+ const int row_height;
+ float ymin_offset = 0;
+
+ int xmin;
+ int xmax;
+ uiBlock &block;
+ const View2D &v2d;
+ DatasetDrawContext &draw_context;
+
+ DatasetRegionDrawer(const ARegion *region, uiBlock &block, DatasetDrawContext &draw_context);
+
+ void draw_hierarchy(const DatasetLayoutHierarchy &layout);
+
+ void draw_attribute_domain_row(const DatasetComponentLayoutInfo &component,
+ const DatasetAttrDomainLayoutInfo &domain_info);
+ void draw_component_row(const DatasetComponentLayoutInfo &component_info);
+
+ private:
+ void draw_dataset_row(const int indentation,
+ const GeometryComponentType component,
+ const std::optional<AttributeDomain> domain,
+ const BIFIconID icon,
+ const char *label,
+ const bool is_active);
+};
+
+void draw_dataset_in_region(const bContext *C, ARegion *region);
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc
new file mode 100644
index 00000000000..e9f2c51a6da
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc
@@ -0,0 +1,112 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <optional>
+
+#include "BLI_span.hh"
+
+#include "BLT_translation.h"
+
+#include "spreadsheet_dataset_layout.hh"
+
+namespace blender::ed::spreadsheet {
+
+#define ATTR_INFO(type, label, icon) \
+ std::optional<DatasetAttrDomainLayoutInfo> \
+ { \
+ std::in_place, type, label, icon \
+ }
+#define ATTR_INFO_NONE(type) \
+ { \
+ std::nullopt \
+ }
+
+/**
+ * Definion for the component->attribute-domain hierarchy.
+ * Constructed at compile time.
+ *
+ * \warning: Order of attribute-domains matters! It __must__ match the #AttributeDomain definition
+ * and fill gaps with unset optionals (i.e. `std::nullopt`). Would be nice to use array
+ * designators for this (which C++ doesn't support).
+ */
+constexpr DatasetComponentLayoutInfo DATASET_layout_hierarchy[] = {
+ {
+ GEO_COMPONENT_TYPE_MESH,
+ N_("Mesh"),
+ ICON_MESH_DATA,
+ {
+ ATTR_INFO(ATTR_DOMAIN_POINT, N_("Vertex"), ICON_VERTEXSEL),
+ ATTR_INFO(ATTR_DOMAIN_EDGE, N_("Edge"), ICON_EDGESEL),
+ ATTR_INFO(ATTR_DOMAIN_FACE, N_("Face"), ICON_FACESEL),
+ ATTR_INFO(ATTR_DOMAIN_CORNER, N_("Face Corner"), ICON_NODE_CORNER),
+ },
+ },
+ {
+ GEO_COMPONENT_TYPE_CURVE,
+ N_("Curves"),
+ ICON_CURVE_DATA,
+ {
+ ATTR_INFO(ATTR_DOMAIN_POINT, N_("Control Point"), ICON_CURVE_BEZCIRCLE),
+ ATTR_INFO_NONE(ATTR_DOMAIN_EDGE),
+ ATTR_INFO_NONE(ATTR_DOMAIN_CORNER),
+ ATTR_INFO_NONE(ATTR_DOMAIN_FACE),
+ ATTR_INFO(ATTR_DOMAIN_CURVE, N_("Spline"), ICON_CURVE_PATH),
+ },
+ },
+ {
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ N_("Point Cloud"),
+ ICON_POINTCLOUD_DATA,
+ {
+ ATTR_INFO(ATTR_DOMAIN_POINT, N_("Point"), ICON_PARTICLE_POINT),
+ },
+ },
+ {
+ GEO_COMPONENT_TYPE_INSTANCES,
+ N_("Instances"),
+ ICON_EMPTY_AXIS,
+ {},
+ },
+};
+
+#undef ATTR_INFO
+#undef ATTR_INFO_LABEL
+
+DatasetLayoutHierarchy dataset_layout_hierarchy()
+{
+ return DatasetLayoutHierarchy{
+ Span{DATASET_layout_hierarchy, ARRAY_SIZE(DATASET_layout_hierarchy)}};
+}
+
+#ifndef NDEBUG
+/**
+ * Debug-only sanity check for correct attribute domain initialization (order/indices must
+ * match AttributeDomain). This doesn't check for all possible missuses, but should catch the most
+ * likely mistakes.
+ */
+void dataset_layout_hierarchy_sanity_check(const DatasetLayoutHierarchy &hierarchy)
+{
+ for (const DatasetComponentLayoutInfo &component : hierarchy.components) {
+ for (uint i = 0; i < component.attr_domains.size(); i++) {
+ if (component.attr_domains[i]) {
+ BLI_assert(component.attr_domains[i]->type == static_cast<AttributeDomain>(i));
+ }
+ }
+ }
+}
+#endif
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh
new file mode 100644
index 00000000000..d463739a0fa
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh
@@ -0,0 +1,68 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include <array>
+#include <optional>
+
+/* Enum definitions... */
+#include "BKE_attribute.h"
+#include "BKE_geometry_set.h"
+
+#include "BLI_span.hh"
+
+/* More enum definitions... */
+#include "UI_resources.h"
+
+#pragma once
+
+namespace blender::ed::spreadsheet {
+
+struct DatasetAttrDomainLayoutInfo {
+ AttributeDomain type;
+ const char *label;
+ BIFIconID icon;
+
+ constexpr DatasetAttrDomainLayoutInfo(AttributeDomain type, const char *label, BIFIconID icon)
+ : type(type), label(label), icon(icon)
+ {
+ }
+};
+
+struct DatasetComponentLayoutInfo {
+ GeometryComponentType type;
+ const char *label;
+ BIFIconID icon;
+ /** Array of attribute-domains. Has to be fixed size based on #AttributeDomain enum, but not all
+ * values need displaying for all parent components. Hence the optional use. */
+ using AttrDomainArray = std::array<std::optional<DatasetAttrDomainLayoutInfo>, ATTR_DOMAIN_NUM>;
+ const AttrDomainArray attr_domains;
+};
+
+struct DatasetLayoutHierarchy {
+ /** The components for display (with layout info like icon and label). Each component stores
+ * the attribute domains it wants to display (also with layout info like icon and label). */
+ const Span<DatasetComponentLayoutInfo> components;
+};
+
+DatasetLayoutHierarchy dataset_layout_hierarchy();
+
+#ifndef NDEBUG
+void dataset_layout_hierarchy_sanity_check(const DatasetLayoutHierarchy &hierarchy);
+#endif
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh b/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh
index 7e3b79a6706..8be5283fd63 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh
@@ -16,10 +16,23 @@
#pragma once
+#include "BKE_geometry_set.hh"
+
typedef struct SpaceSpreadsheet_Runtime {
int visible_rows;
int tot_rows;
int tot_columns;
} SpaceSpreadsheet_Runtime;
+struct bContext;
+
void spreadsheet_operatortypes(void);
+void spreadsheet_update_context_path(const bContext *C);
+Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet,
+ const Depsgraph *depsgraph);
+
+namespace blender::ed::spreadsheet {
+GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet,
+ Object *object_eval,
+ const GeometryComponentType used_component_type);
+}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
index fcbc37346e6..ceb4cd84cde 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
@@ -13,6 +13,17 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "BKE_screen.h"
+
+#include "DNA_space_types.h"
+
+#include "ED_screen.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
#include "BLI_listbase.h"
@@ -89,8 +100,50 @@ static void SPREADSHEET_OT_remove_row_filter_rule(wmOperatorType *ot)
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
}
+static int select_component_domain_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *UNUSED(event))
+{
+ GeometryComponentType component_type = static_cast<GeometryComponentType>(
+ RNA_int_get(op->ptr, "component_type"));
+ AttributeDomain attribute_domain = static_cast<AttributeDomain>(
+ RNA_int_get(op->ptr, "attribute_domain_type"));
+
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+ sspreadsheet->geometry_component_type = component_type;
+ sspreadsheet->attribute_domain = attribute_domain;
+
+ /* Refresh header and main region. */
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SPREADSHEET_OT_change_spreadsheet_data_source(wmOperatorType *ot)
+{
+ ot->name = "Change Visible Data Source";
+ ot->description = "Change visible data source in the spreadsheet";
+ ot->idname = "SPREADSHEET_OT_change_spreadsheet_data_source";
+
+ ot->invoke = select_component_domain_invoke;
+
+ RNA_def_int(ot->srna, "component_type", 0, 0, INT16_MAX, "Component Type", "", 0, INT16_MAX);
+ RNA_def_int(ot->srna,
+ "attribute_domain_type",
+ 0,
+ 0,
+ INT16_MAX,
+ "Attribute Domain Type",
+ "",
+ 0,
+ INT16_MAX);
+
+ ot->flag = OPTYPE_INTERNAL;
+}
+
void spreadsheet_operatortypes()
{
WM_operatortype_append(SPREADSHEET_OT_add_row_filter_rule);
WM_operatortype_append(SPREADSHEET_OT_remove_row_filter_rule);
+ WM_operatortype_append(SPREADSHEET_OT_change_spreadsheet_data_source);
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index ad1b52bdfd7..17062b399cd 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -776,6 +776,20 @@ static void rna_Space_show_region_toolbar_update(bContext *C, PointerRNA *ptr)
rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_TOOLS, RGN_FLAG_HIDDEN);
}
+/* Channels Region. */
+static bool rna_Space_show_region_channels_get(PointerRNA *ptr)
+{
+ return !rna_Space_bool_from_region_flag_get_by_type(ptr, RGN_TYPE_CHANNELS, RGN_FLAG_HIDDEN);
+}
+static void rna_Space_show_region_channels_set(PointerRNA *ptr, bool value)
+{
+ rna_Space_bool_from_region_flag_set_by_type(ptr, RGN_TYPE_CHANNELS, RGN_FLAG_HIDDEN, !value);
+}
+static void rna_Space_show_region_channels_update(bContext *C, PointerRNA *ptr)
+{
+ rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_CHANNELS, RGN_FLAG_HIDDEN);
+}
+
/* UI Region */
static bool rna_Space_show_region_ui_get(PointerRNA *ptr)
{
@@ -3214,6 +3228,10 @@ static void rna_def_space_generic_show_region_toggles(StructRNA *srna, int regio
region_type_mask &= ~(1 << RGN_TYPE_TOOLS);
DEF_SHOW_REGION_PROPERTY(show_region_toolbar, "Toolbar", "");
}
+ if (region_type_mask & (1 << RGN_TYPE_CHANNELS)) {
+ region_type_mask &= ~(1 << RGN_TYPE_CHANNELS);
+ DEF_SHOW_REGION_PROPERTY(show_region_channels, "Channels", "");
+ }
if (region_type_mask & (1 << RGN_TYPE_UI)) {
region_type_mask &= ~(1 << RGN_TYPE_UI);
DEF_SHOW_REGION_PROPERTY(show_region_ui, "Sidebar", "");
@@ -7560,6 +7578,9 @@ static void rna_def_space_spreadsheet_context(BlenderRNA *brna)
RNA_def_property_enum_items(prop, spreadsheet_context_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of the context");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ rna_def_space_generic_show_region_toggles(srna,
+ (1 << RGN_TYPE_CHANNELS) | (1 << RGN_TYPE_FOOTER));
}
static void rna_def_space_spreadsheet_context_object(BlenderRNA *brna)
@@ -7674,7 +7695,7 @@ static void rna_def_space_spreadsheet(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SpaceSpreadsheet", "Space");
RNA_def_struct_ui_text(srna, "Space Spreadsheet", "Spreadsheet space data");
- rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI) | (1 << RGN_TYPE_FOOTER));
+ rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI) | (1 << RGN_TYPE_CHANNELS) | (1 << RGN_TYPE_FOOTER) );
prop = RNA_def_property(srna, "is_pinned", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPREADSHEET_FLAG_PINNED);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 70c57119e2d..92d8b299099 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3864,6 +3864,7 @@ static void rna_def_userdef_theme_space_spreadsheet(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
rna_def_userdef_theme_spaces_main(srna);
+ rna_def_userdef_theme_spaces_list_main(srna);
}
static void rna_def_userdef_themes(BlenderRNA *brna)