Cleanup: Geometry Nodes: reduce boilerplate for ui-lists for socket items

This commit is contained in:
Jacques Lucke
2024-10-03 22:53:04 +02:00
parent 26c25305f5
commit bfc1fb8f83
14 changed files with 184 additions and 456 deletions

View File

@@ -123,6 +123,7 @@ set(SRC
NOD_socket_declarations_geometry.hh
NOD_socket_items.hh
NOD_socket_items_ops.hh
NOD_socket_items_ui.hh
NOD_socket_search_link.hh
NOD_static_types.h
NOD_texture.h

View File

@@ -0,0 +1,93 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "WM_api.hh"
#include "UI_interface.hh"
#include "RNA_access.hh"
#include "RNA_prototypes.hh"
#include "BKE_screen.hh"
namespace blender::nodes::socket_items::ui {
template<typename Accessor>
static void draw_item_in_list(uiList * /*ui_list*/,
const bContext *C,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayout *row = uiLayoutRow(layout, true);
if constexpr (Accessor::has_type) {
float4 color;
RNA_float_get_array(itemptr, "color", color);
uiTemplateNodeSocket(row, const_cast<bContext *>(C), color);
}
uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
uiItemR(row, itemptr, "name", UI_ITEM_NONE, "", ICON_NONE);
}
/**
* Draws a ui-list that contains the items. The list also has operators to add, remove and reorder
* items.
*/
template<typename Accessor>
static void draw_items_list_with_operators(const bContext *C,
uiLayout *layout,
const bNodeTree &tree,
const bNode &node)
{
BLI_assert(Accessor::node_type == node.type);
PointerRNA node_ptr = RNA_pointer_create(
const_cast<ID *>(&tree.id), &RNA_Node, const_cast<bNode *>(&node));
static const uiListType *items_list = []() {
uiListType *list = MEM_cnew<uiListType>(Accessor::ui_idnames::list);
STRNCPY(list->idname, Accessor::ui_idnames::list);
list->draw_item = draw_item_in_list<Accessor>;
WM_uilisttype_add(list);
return list;
}();
uiLayout *row = uiLayoutRow(layout, false);
uiTemplateList(row,
C,
items_list->idname,
"",
&node_ptr,
Accessor::rna_names::items,
&node_ptr,
Accessor::rna_names::active_index,
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(add_remove_col, "", ICON_ADD, Accessor::operator_idnames::add_item);
uiItemO(add_remove_col, "", ICON_REMOVE, Accessor::operator_idnames::remove_item);
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(
up_down_col, Accessor::operator_idnames::move_item, "", ICON_TRIA_UP, "direction", 0);
uiItemEnumO(
up_down_col, Accessor::operator_idnames::move_item, "", ICON_TRIA_DOWN, "direction", 1);
}
}
} // namespace blender::nodes::socket_items::ui

View File

@@ -40,6 +40,13 @@ struct BakeItemsAccessor {
static constexpr const char *remove_item = "NODE_OT_bake_node_item_remove";
static constexpr const char *move_item = "NODE_OT_bake_node_item_move";
};
struct ui_idnames {
static constexpr const char *list = "DATA_UL_bake_node_items";
};
struct rna_names {
static constexpr const char *items = "bake_items";
static constexpr const char *active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeGeometryBakeItem> get_items_from_node(bNode &node)
{

View File

@@ -25,6 +25,13 @@ struct CaptureAttributeItemsAccessor {
static constexpr const char *remove_item = "NODE_OT_capture_attribute_item_remove";
static constexpr const char *move_item = "NODE_OT_capture_attribute_item_move";
};
struct ui_idnames {
static constexpr const char *list = "NODE_UL_capture_items_list";
};
struct rna_names {
static constexpr const char *items = "capture_items";
static constexpr const char *active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeGeometryAttributeCaptureItem> get_items_from_node(
bNode &node)

View File

@@ -25,6 +25,13 @@ struct ForeachGeometryElementInputItemsAccessor {
static constexpr const char *move_item =
"NODE_OT_foreach_geometry_element_zone_input_item_move";
};
struct ui_idnames {
static constexpr const char *list = "DATA_UL_foreach_geometry_element_input_items";
};
struct rna_names {
static constexpr const char *items = "input_items";
static constexpr const char *active_index = "active_input_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
@@ -104,6 +111,13 @@ struct ForeachGeometryElementMainItemsAccessor {
static constexpr const char *move_item =
"NODE_OT_foreach_geometry_element_zone_main_item_move";
};
struct ui_idnames {
static constexpr const char *list = "DATA_UL_foreach_geometry_element_main_items";
};
struct rna_names {
static constexpr const char *items = "main_items";
static constexpr const char *active_index = "active_main_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
@@ -183,6 +197,13 @@ struct ForeachGeometryElementGenerationItemsAccessor {
static constexpr const char *move_item =
"NODE_OT_foreach_geometry_element_zone_generation_item_move";
};
struct ui_idnames {
static constexpr const char *list = "DATA_UL_foreach_geometry_element_generation_items";
};
struct rna_names {
static constexpr const char *items = "generation_items";
static constexpr const char *active_index = "active_generation_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{

View File

@@ -28,6 +28,13 @@ struct MenuSwitchItemsAccessor {
static constexpr const char *remove_item = "NODE_OT_enum_definition_item_remove";
static constexpr const char *move_item = "NODE_OT_enum_definition_item_move";
};
struct ui_idnames {
static constexpr const char *list = "NODE_UL_enum_definition_items";
};
struct rna_names {
static constexpr const char *items = "enum_items";
static constexpr const char *active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeEnumItem> get_items_from_node(bNode &node)
{

View File

@@ -28,6 +28,13 @@ struct RepeatItemsAccessor {
static constexpr const char *remove_item = "NODE_OT_repeat_zone_item_remove";
static constexpr const char *move_item = "NODE_OT_repeat_zone_item_move";
};
struct ui_idnames {
static constexpr const char *list = "DATA_UL_repeat_zone_state";
};
struct rna_names {
static constexpr const char *items = "repeat_items";
static constexpr const char *active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeRepeatItem> get_items_from_node(bNode &node)
{

View File

@@ -27,6 +27,13 @@ struct SimulationItemsAccessor {
static constexpr const char *remove_item = "NODE_OT_simulation_zone_item_remove";
static constexpr const char *move_item = "NODE_OT_simulation_zone_item_move";
};
struct ui_idnames {
static constexpr const char *list = "DATA_UL_simulation_zone_state";
};
struct rna_names {
static constexpr const char *items = "state_items";
static constexpr const char *active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeSimulationItem> get_items_from_node(bNode &node)
{

View File

@@ -9,6 +9,7 @@
#include "NOD_geo_capture_attribute.hh"
#include "NOD_socket_items_ops.hh"
#include "NOD_socket_items_ui.hh"
#include "NOD_socket_search_link.hh"
#include "RNA_enum_types.hh"
@@ -66,80 +67,27 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static void draw_item(uiList * /*ui_list*/,
const bContext *C,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayout *row = uiLayoutRow(layout, true);
float4 color;
RNA_float_get_array(itemptr, "color", color);
uiTemplateNodeSocket(row, const_cast<bContext *>(C), color);
uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
uiItemR(row, itemptr, "name", UI_ITEM_NONE, "", ICON_NONE);
}
static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
static const uiListType *items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "NODE_UL_capture_items_list");
list->draw_item = draw_item;
WM_uilisttype_add(list);
return list;
}();
bNodeTree &tree = *reinterpret_cast<bNodeTree *>(ptr->owner_id);
bNode &node = *static_cast<bNode *>(ptr->data);
uiItemR(layout, ptr, "domain", UI_ITEM_NONE, "", ICON_NONE);
if (uiLayout *panel = uiLayoutPanel(
C, layout, "capture_attribute_items", false, TIP_("Capture Items")))
{
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
items_list->idname,
"",
ptr,
"capture_items",
ptr,
"active_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(add_remove_col, "", ICON_ADD, "node.capture_attribute_item_add");
uiItemO(add_remove_col, "", ICON_REMOVE, "node.capture_attribute_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(
up_down_col, "node.capture_attribute_item_move", "", ICON_TRIA_UP, "direction", 0);
uiItemEnumO(
up_down_col, "node.capture_attribute_item_move", "", ICON_TRIA_DOWN, "direction", 1);
}
bNode &node = *static_cast<bNode *>(ptr->data);
auto &storage = node_storage(node);
if (storage.active_index >= 0 && storage.active_index < storage.capture_items_num) {
NodeGeometryAttributeCaptureItem &active_item =
storage.capture_items[storage.active_index];
PointerRNA item_ptr = RNA_pointer_create(
ptr->owner_id, CaptureAttributeItemsAccessor::item_srna, &active_item);
uiLayoutSetPropSep(panel, true);
uiLayoutSetPropDecorate(panel, false);
uiItemR(panel, &item_ptr, "data_type", UI_ITEM_NONE, nullptr, ICON_NONE);
}
socket_items::ui::draw_items_list_with_operators<CaptureAttributeItemsAccessor>(
C, panel, tree, node);
auto &storage = node_storage(node);
if (storage.active_index >= 0 && storage.active_index < storage.capture_items_num) {
NodeGeometryAttributeCaptureItem &active_item = storage.capture_items[storage.active_index];
PointerRNA item_ptr = RNA_pointer_create(
ptr->owner_id, CaptureAttributeItemsAccessor::item_srna, &active_item);
uiLayoutSetPropSep(panel, true);
uiLayoutSetPropDecorate(panel, false);
uiItemR(panel, &item_ptr, "data_type", UI_ITEM_NONE, nullptr, ICON_NONE);
}
}
}

View File

@@ -8,6 +8,7 @@
#include "NOD_node_extra_info.hh"
#include "NOD_rna_define.hh"
#include "NOD_socket_items_ops.hh"
#include "NOD_socket_items_ui.hh"
#include "NOD_socket_search_link.hh"
#include "UI_interface.hh"
@@ -126,67 +127,13 @@ static const CPPType &get_item_cpp_type(const eNodeSocketDatatype socket_type)
return *typeinfo->geometry_nodes_cpp_type;
}
static void draw_bake_item(uiList * /*ui_list*/,
const bContext *C,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayout *row = uiLayoutRow(layout, true);
float4 color;
RNA_float_get_array(itemptr, "color", color);
uiTemplateNodeSocket(row, const_cast<bContext *>(C), color);
uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
uiItemR(row, itemptr, "name", UI_ITEM_NONE, "", ICON_NONE);
}
static void draw_bake_items(const bContext *C, uiLayout *layout, PointerRNA node_ptr)
{
static const uiListType *bake_items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "DATA_UL_bake_node_items");
list->draw_item = draw_bake_item;
WM_uilisttype_add(list);
return list;
}();
bNodeTree &tree = *reinterpret_cast<bNodeTree *>(node_ptr.owner_id);
bNode &node = *static_cast<bNode *>(node_ptr.data);
if (uiLayout *panel = uiLayoutPanel(C, layout, "bake_items", false, TIP_("Bake Items"))) {
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
bake_items_list->idname,
"",
&node_ptr,
"bake_items",
&node_ptr,
"active_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(add_remove_col, "", ICON_ADD, "node.bake_node_item_add");
uiItemO(add_remove_col, "", ICON_REMOVE, "node.bake_node_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(up_down_col, "node.bake_node_item_move", "", ICON_TRIA_UP, "direction", 0);
uiItemEnumO(up_down_col, "node.bake_node_item_move", "", ICON_TRIA_DOWN, "direction", 1);
}
}
socket_items::ui::draw_items_list_with_operators<BakeItemsAccessor>(C, panel, tree, node);
NodeGeometryBake &storage = node_storage(node);
if (storage.active_index >= 0 && storage.active_index < storage.items_num) {

View File

@@ -14,6 +14,7 @@
#include "NOD_geo_foreach_geometry_element.hh"
#include "NOD_node_extra_info.hh"
#include "NOD_socket_items_ops.hh"
#include "NOD_socket_items_ui.hh"
#include "UI_interface.hh"
#include "UI_resources.hh"
@@ -24,25 +25,6 @@
namespace blender::nodes::node_geo_foreach_geometry_element_cc {
static void draw_item(uiList * /*ui_list*/,
const bContext *C,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayout *row = uiLayoutRow(layout, true);
float4 color;
RNA_float_get_array(itemptr, "color", color);
uiTemplateNodeSocket(row, const_cast<bContext *>(C), color);
uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
uiItemR(row, itemptr, "name", UI_ITEM_NONE, "", ICON_NONE);
}
/** Shared between zone input and output node. */
static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *current_node_ptr)
{
@@ -68,55 +50,8 @@ static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *current_no
if (is_zone_input_node) {
if (uiLayout *panel = uiLayoutPanel(C, layout, "input", false, TIP_("Input Fields"))) {
static const uiListType *input_items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "DATA_UL_foreach_geometry_element_input_items");
list->draw_item = draw_item;
WM_uilisttype_add(list);
return list;
}();
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
input_items_list->idname,
"",
&output_node_ptr,
"input_items",
&output_node_ptr,
"active_input_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(
add_remove_col, "", ICON_ADD, "node.foreach_geometry_element_zone_input_item_add");
uiItemO(add_remove_col,
"",
ICON_REMOVE,
"node.foreach_geometry_element_zone_input_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(up_down_col,
"node.foreach_geometry_element_zone_input_item_move",
"",
ICON_TRIA_UP,
"direction",
0);
uiItemEnumO(up_down_col,
"node.foreach_geometry_element_zone_input_item_move",
"",
ICON_TRIA_DOWN,
"direction",
1);
}
}
socket_items::ui::draw_items_list_with_operators<ForeachGeometryElementInputItemsAccessor>(
C, panel, ntree, output_node);
if (storage.input_items.active_index >= 0 &&
storage.input_items.active_index < storage.input_items.items_num)
@@ -135,55 +70,8 @@ static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *current_no
}
else {
if (uiLayout *panel = uiLayoutPanel(C, layout, "main_items", false, TIP_("Main Geometry"))) {
static const uiListType *main_items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "DATA_UL_foreach_geometry_element_main_items");
list->draw_item = draw_item;
WM_uilisttype_add(list);
return list;
}();
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
main_items_list->idname,
"",
&output_node_ptr,
"main_items",
&output_node_ptr,
"active_main_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(
add_remove_col, "", ICON_ADD, "node.foreach_geometry_element_zone_main_item_add");
uiItemO(add_remove_col,
"",
ICON_REMOVE,
"node.foreach_geometry_element_zone_main_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(up_down_col,
"node.foreach_geometry_element_zone_main_item_move",
"",
ICON_TRIA_UP,
"direction",
0);
uiItemEnumO(up_down_col,
"node.foreach_geometry_element_zone_main_item_move",
"",
ICON_TRIA_DOWN,
"direction",
1);
}
}
socket_items::ui::draw_items_list_with_operators<ForeachGeometryElementMainItemsAccessor>(
C, panel, ntree, output_node);
if (storage.main_items.active_index >= 0 &&
storage.main_items.active_index < storage.main_items.items_num)
@@ -202,57 +90,8 @@ static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *current_no
if (uiLayout *panel = uiLayoutPanel(
C, layout, "generation_items", false, TIP_("Generated Geometry")))
{
static const uiListType *generation_items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "DATA_UL_foreach_geometry_element_generation_items");
list->draw_item = draw_item;
WM_uilisttype_add(list);
return list;
}();
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
generation_items_list->idname,
"",
&output_node_ptr,
"generation_items",
&output_node_ptr,
"active_generation_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(add_remove_col,
"",
ICON_ADD,
"node.foreach_geometry_element_zone_generation_item_add");
uiItemO(add_remove_col,
"",
ICON_REMOVE,
"node.foreach_geometry_element_zone_generation_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(up_down_col,
"node.foreach_geometry_element_zone_generation_item_move",
"",
ICON_TRIA_UP,
"direction",
0);
uiItemEnumO(up_down_col,
"node.foreach_geometry_element_zone_generation_item_move",
"",
ICON_TRIA_DOWN,
"direction",
1);
}
}
socket_items::ui::draw_items_list_with_operators<
ForeachGeometryElementGenerationItemsAccessor>(C, panel, ntree, output_node);
if (storage.generation_items.active_index >= 0 &&
storage.generation_items.active_index < storage.generation_items.items_num)

View File

@@ -19,6 +19,7 @@
#include "NOD_rna_define.hh"
#include "NOD_socket.hh"
#include "NOD_socket_items_ops.hh"
#include "NOD_socket_items_ui.hh"
#include "NOD_socket_search_link.hh"
#include "BLO_read_write.hh"
@@ -357,66 +358,16 @@ class LazyFunctionForMenuSwitchSocketUsage : public lf::LazyFunction {
}
};
static void draw_menu_switch_item(uiList * /*ui_list*/,
const bContext * /*C*/,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayoutSetEmboss(layout, UI_EMBOSS_NONE);
uiItemR(layout, itemptr, "name", UI_ITEM_NONE, "", ICON_NONE);
}
static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNodeTree &tree = *reinterpret_cast<bNodeTree *>(ptr->owner_id);
bNode &node = *static_cast<bNode *>(ptr->data);
static const uiListType *menu_items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "NODE_UL_enum_definition_items");
list->draw_item = draw_menu_switch_item;
WM_uilisttype_add(list);
return list;
}();
uiItemR(layout, ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
if (uiLayout *panel = uiLayoutPanel(C, layout, "menu_switch_items", false, TIP_("Menu Items"))) {
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
menu_items_list->idname,
"",
ptr,
"enum_items",
ptr,
"active_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(add_remove_col, "", ICON_ADD, "node.enum_definition_item_add");
uiItemO(add_remove_col, "", ICON_REMOVE, "node.enum_definition_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(
up_down_col, "node.enum_definition_item_move", "", ICON_TRIA_UP, "direction", 0);
uiItemEnumO(
up_down_col, "node.enum_definition_item_move", "", ICON_TRIA_DOWN, "direction", 1);
}
}
socket_items::ui::draw_items_list_with_operators<MenuSwitchItemsAccessor>(
C, panel, tree, node);
auto &storage = node_storage(node);
if (storage.enum_definition.active_index >= 0 &&

View File

@@ -8,6 +8,7 @@
#include "NOD_geo_repeat.hh"
#include "NOD_socket.hh"
#include "NOD_socket_items_ops.hh"
#include "NOD_socket_items_ui.hh"
#include "BLO_read_write.hh"
@@ -26,25 +27,6 @@
namespace blender::nodes::node_geo_repeat_cc {
static void draw_repeat_state_item(uiList * /*ui_list*/,
const bContext *C,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayout *row = uiLayoutRow(layout, true);
float4 color;
RNA_float_get_array(itemptr, "color", color);
uiTemplateNodeSocket(row, const_cast<bContext *>(C), color);
uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
uiItemR(row, itemptr, "name", UI_ITEM_NONE, "", ICON_NONE);
}
/** Shared between repeat zone input and output node. */
static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *current_node_ptr)
{
@@ -66,43 +48,9 @@ static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *current_no
PointerRNA output_node_ptr = RNA_pointer_create(
current_node_ptr->owner_id, &RNA_Node, &output_node);
static const uiListType *state_items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "DATA_UL_repeat_zone_state");
list->draw_item = draw_repeat_state_item;
WM_uilisttype_add(list);
return list;
}();
if (uiLayout *panel = uiLayoutPanel(C, layout, "repeat_items", false, TIP_("Repeat Items"))) {
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
state_items_list->idname,
"",
&output_node_ptr,
"repeat_items",
&output_node_ptr,
"active_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(add_remove_col, "", ICON_ADD, "node.repeat_zone_item_add");
uiItemO(add_remove_col, "", ICON_REMOVE, "node.repeat_zone_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(up_down_col, "node.repeat_zone_item_move", "", ICON_TRIA_UP, "direction", 0);
uiItemEnumO(up_down_col, "node.repeat_zone_item_move", "", ICON_TRIA_DOWN, "direction", 1);
}
}
socket_items::ui::draw_items_list_with_operators<RepeatItemsAccessor>(
C, panel, ntree, output_node);
auto &storage = *static_cast<NodeGeometryRepeatOutput *>(output_node.storage);
if (storage.active_index >= 0 && storage.active_index < storage.items_num) {
NodeRepeatItem &active_item = storage.items[storage.active_index];

View File

@@ -35,6 +35,7 @@
#include "NOD_node_extra_info.hh"
#include "NOD_socket.hh"
#include "NOD_socket_items_ops.hh"
#include "NOD_socket_items_ui.hh"
#include "DNA_curves_types.h"
#include "DNA_mesh_types.h"
@@ -192,74 +193,18 @@ static bke::bake::BakeState move_values_to_simulation_state(
return bake_state;
}
static void draw_simulation_state_item(uiList * /*ui_list*/,
const bContext *C,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayout *row = uiLayoutRow(layout, true);
float4 color;
RNA_float_get_array(itemptr, "color", color);
uiTemplateNodeSocket(row, const_cast<bContext *>(C), color);
uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
uiItemR(row, itemptr, "name", UI_ITEM_NONE, "", ICON_NONE);
}
static void draw_simulation_state(const bContext *C,
uiLayout *layout,
bNodeTree &ntree,
bNode &output_node)
{
static const uiListType *state_items_list = []() {
uiListType *list = MEM_cnew<uiListType>(__func__);
STRNCPY(list->idname, "DATA_UL_simulation_zone_state");
list->draw_item = draw_simulation_state_item;
WM_uilisttype_add(list);
return list;
}();
PointerRNA output_node_ptr = RNA_pointer_create(&ntree.id, &RNA_Node, &output_node);
if (uiLayout *panel = uiLayoutPanel(
C, layout, "simulation_state_items", false, TIP_("Simulation State")))
{
uiLayout *row = uiLayoutRow(panel, false);
uiTemplateList(row,
C,
state_items_list->idname,
"",
&output_node_ptr,
"state_items",
&output_node_ptr,
"active_index",
nullptr,
3,
5,
UILST_LAYOUT_DEFAULT,
0,
UI_TEMPLATE_LIST_FLAG_NONE);
{
uiLayout *ops_col = uiLayoutColumn(row, false);
{
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
uiItemO(add_remove_col, "", ICON_ADD, "node.simulation_zone_item_add");
uiItemO(add_remove_col, "", ICON_REMOVE, "node.simulation_zone_item_remove");
}
{
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
uiItemEnumO(
up_down_col, "node.simulation_zone_item_move", "", ICON_TRIA_UP, "direction", 0);
uiItemEnumO(
up_down_col, "node.simulation_zone_item_move", "", ICON_TRIA_DOWN, "direction", 1);
}
}
socket_items::ui::draw_items_list_with_operators<SimulationItemsAccessor>(
C, panel, ntree, output_node);
auto &storage = *static_cast<NodeGeometrySimulationOutput *>(output_node.storage);
if (storage.active_index >= 0 && storage.active_index < storage.items_num) {