24#include "RNA_prototypes.hh"
39using node_interface::bNodeTreeInterfaceItemReference;
41class NodePanelViewItem;
42class NodeSocketViewItem;
43class NodeTreeInterfaceView;
45class NodeTreeInterfaceDragController :
public AbstractViewItemDragController {
51 explicit NodeTreeInterfaceDragController(NodeTreeInterfaceView &
view,
54 ~NodeTreeInterfaceDragController()
override =
default;
56 std::optional<eWM_DragDataType> get_drag_type()
const override;
58 void *create_drag_data()
const override;
61class NodeSocketDropTarget :
public TreeViewItemDropTarget {
68 bool can_drop(
const wmDrag &drag,
const char **r_disabled_hint)
const override;
69 std::string drop_tooltip(
const DragInfo &drag_info)
const override;
70 bool on_drop(bContext * ,
const DragInfo &drag_info)
const override;
73class NodePanelDropTarget :
public TreeViewItemDropTarget {
80 bool can_drop(
const wmDrag &drag,
const char **r_disabled_hint)
const override;
81 std::string drop_tooltip(
const DragInfo &drag_info)
const override;
82 bool on_drop(bContext *
C,
const DragInfo &drag_info)
const override;
85class NodeSocketViewItem :
public BasicTreeViewItem {
94 : BasicTreeViewItem(socket.
name, ICON_NONE), nodetree_(nodetree), socket_(socket)
96 set_is_active_fn([interface, &socket]() {
return interface.active_item() == &socket.
item; });
97 set_on_activate_fn([&interface](bContext & , BasicTreeViewItem &new_active) {
98 NodeSocketViewItem &
self =
static_cast<NodeSocketViewItem &
>(new_active);
103 void build_row(uiLayout &row)
override
111 uiLayout *input_socket_layout = &row.
row(
true);
118 input_socket_layout->
label(
"", ICON_BLANK1);
121 this->add_label(row,
IFACE_(label_.c_str()));
123 uiLayout *output_socket_layout = &row.
row(
true);
130 output_socket_layout->
label(
"", ICON_BLANK1);
135 bool matches(
const AbstractViewItem &other)
const override
137 const NodeSocketViewItem *other_item =
dynamic_cast<const NodeSocketViewItem *
>(&other);
138 if (other_item ==
nullptr) {
142 return &socket_ == &other_item->socket_;
145 bool supports_renaming()
const override
149 bool rename(
const bContext &
C, StringRefNull new_name)
override
154 nodetree_.tree_interface.tag_item_property_changed();
159 StringRef get_rename_string()
const override
164 void delete_item(bContext *
C)
override
167 nodetree_.tree_interface.remove_item(socket_.item);
173 std::unique_ptr<AbstractViewItemDragController> create_drag_controller()
const override;
174 std::unique_ptr<TreeViewItemDropTarget> create_drop_target()
override;
177class NodePanelViewItem :
public BasicTreeViewItem {
187 : BasicTreeViewItem(panel.
name, ICON_NONE), nodetree_(nodetree), panel_(panel)
189 set_is_active_fn([interface, &panel]() {
return interface.active_item() == &panel.
item; });
190 set_on_activate_fn([&interface](bContext & , BasicTreeViewItem &new_active) {
191 NodePanelViewItem &
self =
static_cast<NodePanelViewItem &
>(new_active);
194 toggle_ = panel.header_toggle_socket();
195 is_always_collapsible_ =
true;
198 void build_row(uiLayout &row)
override
204 if (toggle_ !=
nullptr) {
205 uiLayout *toggle_layout = &row.
row(
true);
210 this->add_label(row,
IFACE_(label_.c_str()));
212 uiLayout *sub = &row.
row(
true);
217 bool matches(
const AbstractViewItem &other)
const override
219 const NodePanelViewItem *other_item =
dynamic_cast<const NodePanelViewItem *
>(&other);
220 if (other_item ==
nullptr) {
224 return &panel_ == &other_item->panel_;
227 std::optional<bool> should_be_collapsed()
const override
232 bool set_collapsed(
const bool collapsed)
override
241 bool supports_renaming()
const override
245 bool rename(
const bContext &
C, StringRefNull new_name)
override
248 &nodetree_.id, &RNA_NodeTreeInterfacePanel, &panel_);
254 StringRef get_rename_string()
const override
259 void delete_item(bContext *
C)
override
262 nodetree_.tree_interface.remove_item(panel_.item);
268 std::unique_ptr<AbstractViewItemDragController> create_drag_controller()
const override;
269 std::unique_ptr<TreeViewItemDropTarget> create_drop_target()
override;
272class NodeTreeInterfaceView :
public AbstractTreeView {
279 : nodetree_(nodetree), interface_(
interface)
293 void build_tree()
override
296 this->add_items_for_panel_recursive(interface_.root_panel, *
this);
305 if (item == skip_item) {
312 NodeSocketViewItem &socket_item = parent_item.add_tree_item<NodeSocketViewItem>(
313 nodetree_, interface_, *socket);
314 socket_item.uncollapse_by_default();
320 NodePanelViewItem &panel_item = parent_item.add_tree_item<NodePanelViewItem>(
321 nodetree_, interface_, *panel);
322 panel_item.uncollapse_by_default();
325 add_items_for_panel_recursive(
334std::unique_ptr<AbstractViewItemDragController> NodeSocketViewItem::create_drag_controller()
const
339 return std::make_unique<NodeTreeInterfaceDragController>(
340 static_cast<NodeTreeInterfaceView &
>(this->get_tree_view()), socket_.
item, nodetree_);
343std::unique_ptr<TreeViewItemDropTarget> NodeSocketViewItem::create_drop_target()
345 return std::make_unique<NodeSocketDropTarget>(*
this, socket_);
348std::unique_ptr<AbstractViewItemDragController> NodePanelViewItem::create_drag_controller()
const
353 return std::make_unique<NodeTreeInterfaceDragController>(
354 static_cast<NodeTreeInterfaceView &
>(this->get_tree_view()), panel_.
item, nodetree_);
357std::unique_ptr<TreeViewItemDropTarget> NodePanelViewItem::create_drop_target()
359 return std::make_unique<NodePanelDropTarget>(*
this, panel_);
362NodeTreeInterfaceDragController::NodeTreeInterfaceDragController(NodeTreeInterfaceView &
view,
365 : AbstractViewItemDragController(
view), item_(item), tree_(
tree)
369std::optional<eWM_DragDataType> NodeTreeInterfaceDragController::get_drag_type()
const
374void *NodeTreeInterfaceDragController::create_drag_data()
const
378 drag_data->
item = &item_;
379 drag_data->
tree = &tree_;
398 if (panel->contains(drop_target_item)) {
405NodeSocketDropTarget::NodeSocketDropTarget(NodeSocketViewItem &item,
411bool NodeSocketDropTarget::can_drop(
const wmDrag &drag,
const char ** )
const
416 if (is_dragging_parent_panel(drag, socket_.
item)) {
422std::string NodeSocketDropTarget::drop_tooltip(
const DragInfo &drag_info)
const
424 switch (drag_info.drop_location) {
425 case DropLocation::Into:
427 case DropLocation::Before:
428 return TIP_(
"Insert before socket");
429 case DropLocation::After:
430 return TIP_(
"Insert after socket");
436 const DragInfo &drag_info,
452 switch (drag_info.drop_location) {
453 case DropLocation::Before:
454 index = parent->items().as_span().first_index_try(&drop_target_item);
456 case DropLocation::After:
457 index = parent->items().as_span().first_index_try(&drop_target_item) + 1;
464 if (parent ==
nullptr || index < 0) {
468 interface.move_item_to_parent(*drag_item, parent, index);
476bool NodeSocketDropTarget::on_drop(
bContext *
C,
const DragInfo &drag_info)
const
478 bNodeTree &nodetree = this->get_view<NodeTreeInterfaceView>().nodetree();
479 return on_drop_flat_item(
C, drag_info, nodetree, socket_.
item);
487bool NodePanelDropTarget::can_drop(
const wmDrag &drag,
const char ** )
const
498 if (panel->contains(panel_.
item)) {
506std::string NodePanelDropTarget::drop_tooltip(
const DragInfo &drag_info)
const
508 switch (drag_info.drop_location) {
509 case DropLocation::Into:
510 return TIP_(
"Insert into panel");
511 case DropLocation::Before:
512 return TIP_(
"Insert before panel");
513 case DropLocation::After:
514 return TIP_(
"Insert after panel");
519bool NodePanelDropTarget::on_drop(
bContext *
C,
const DragInfo &drag_info)
const
526 bNodeTree &nodetree = get_view<NodeTreeInterfaceView>().nodetree();
531 switch (drag_info.drop_location) {
532 case DropLocation::Into: {
535 const bool has_toggle_socket = panel_.header_toggle_socket() != nullptr;
536 index = has_toggle_socket ? 1 : 0;
539 case DropLocation::Before: {
541 parent = interface.find_item_parent(panel_.item, true);
542 BLI_assert(parent != nullptr);
543 index = parent->items().as_span().first_index_try(&panel_.item);
546 case DropLocation::After: {
548 parent = interface.find_item_parent(panel_.item, true);
549 BLI_assert(parent != nullptr);
550 index = parent->items().as_span().first_index_try(&panel_.item) + 1;
554 if (parent ==
nullptr || index < 0) {
558 interface.move_item_to_parent(*drag_item, parent, index);
585 "Node Tree Declaration Tree View",
586 std::make_unique<blender::ui::nodes::NodeTreeInterfaceView>(nodetree,
interface));
Main * CTX_data_main(const bContext *C)
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
#define BLI_assert_unreachable()
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ID_IS_LINKED(_id)
#define ID_IS_EDITABLE(_id)
NodeTreeInterfaceItemType
@ NODE_INTERFACE_PANEL_IS_COLLAPSED
@ NODE_INTERFACE_SOCKET_OUTPUT
@ NODE_INTERFACE_SOCKET_INPUT
struct bNodeTreeInterface bNodeTreeInterface
struct bNodeTreeInterfaceSocket bNodeTreeInterfaceSocket
struct bNodeTreeInterfacePanel bNodeTreeInterfacePanel
struct bNodeTreeInterfaceItem bNodeTreeInterfaceItem
struct bNodeTree bNodeTree
void ED_undo_push(bContext *C, const char *str)
blender::ui::AbstractGridView * UI_block_add_view(uiBlock &block, blender::StringRef idname, std::unique_ptr< blender::ui::AbstractGridView > grid_view)
void uiTemplateNodeSocket(uiLayout *layout, bContext *C, const float color[4])
@ WM_DRAG_NODE_TREE_INTERFACE
constexpr const char * c_str() const
virtual bool set_collapsed(bool collapsed)
void set_default_rows(int default_rows)
void set_context_menu_title(const std::string &title)
static void build_tree_view(const bContext &C, AbstractTreeView &tree_view, uiLayout &layout, bool add_box=true)
void uiTemplateNodeTreeInterface(uiLayout *layout, const bContext *C, PointerRNA *ptr)
void * MEM_callocN(size_t len, const char *str)
T & get_item_as(bNodeTreeInterfaceItem &item)
TreeViewItemContainer TreeViewOrItem
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
bNodeTreeInterfaceItem item
bNodeTreeInterfaceItem item
bNodeTreeInterfaceItem * item
void use_property_decorate_set(bool is_sep)
void label(blender::StringRef name, int icon)
void enabled_set(bool enabled)
uiLayout & row(bool align)
void WM_main_add_notifier(uint type, void *reference)