Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_node/node_draw.cc
| Show All 21 Lines | |||||
| * \brief higher level node drawing for the node editor. | * \brief higher level node drawing for the node editor. | ||||
| */ | */ | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DNA_light_types.h" | #include "DNA_light_types.h" | ||||
| #include "DNA_linestyle_types.h" | #include "DNA_linestyle_types.h" | ||||
| #include "DNA_material_types.h" | #include "DNA_material_types.h" | ||||
| #include "DNA_modifier_types.h" | |||||
| #include "DNA_node_types.h" | #include "DNA_node_types.h" | ||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "DNA_space_types.h" | #include "DNA_space_types.h" | ||||
| #include "DNA_texture_types.h" | #include "DNA_texture_types.h" | ||||
| #include "DNA_world_types.h" | #include "DNA_world_types.h" | ||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_map.hh" | |||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_string_ref.hh" | |||||
| #include "BLI_vector.hh" | |||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_node_ui_storage.hh" | |||||
| #include "BKE_object.h" | |||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "BLF_api.h" | #include "BLF_api.h" | ||||
| #include "BIF_glutil.h" | #include "BIF_glutil.h" | ||||
| #include "GPU_framebuffer.h" | #include "GPU_framebuffer.h" | ||||
| Show All 16 Lines | |||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "node_intern.h" /* own include */ | #include "node_intern.h" /* own include */ | ||||
| #ifdef WITH_COMPOSITOR | #ifdef WITH_COMPOSITOR | ||||
| # include "COM_compositor.h" | # include "COM_compositor.h" | ||||
| #endif | #endif | ||||
| using blender::Map; | |||||
| using blender::StringRef; | |||||
| using blender::Vector; | |||||
| extern "C" { | extern "C" { | ||||
| /* XXX interface.h */ | /* XXX interface.h */ | ||||
| extern void ui_draw_dropshadow( | extern void ui_draw_dropshadow( | ||||
| const rctf *rct, float radius, float aspect, float alpha, int select); | const rctf *rct, float radius, float aspect, float alpha, int select); | ||||
| } | } | ||||
| float ED_node_grid_size(void) | float ED_node_grid_size(void) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 1,088 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { | ||||
| float outline_color[4]; | float outline_color[4]; | ||||
| node_socket_color_get((bContext *)C, ntree, &node_ptr, socket, color); | node_socket_color_get((bContext *)C, ntree, &node_ptr, socket, color); | ||||
| node_socket_outline_color_get(selected, outline_color); | node_socket_outline_color_get(selected, outline_color); | ||||
| node_socket_draw_multi_input(color, outline_color, width, height, socket->locx, socket->locy); | node_socket_draw_multi_input(color, outline_color, width, height, socket->locx, socket->locy); | ||||
| } | } | ||||
| } | } | ||||
| static int node_error_type_to_icon(const NodeWarningType type) | |||||
| { | |||||
| switch (type) { | |||||
| case NodeWarningType::Error: | |||||
| return ICON_ERROR; | |||||
| case NodeWarningType::Warning: | |||||
| return ICON_ERROR; | |||||
| case NodeWarningType::Info: | |||||
| return ICON_INFO; | |||||
| } | |||||
| BLI_assert(false); | |||||
| return ICON_ERROR; | |||||
| } | |||||
| static uint8_t node_error_type_priority(const NodeWarningType type) | |||||
| { | |||||
| switch (type) { | |||||
| case NodeWarningType::Error: | |||||
| return 3; | |||||
| case NodeWarningType::Warning: | |||||
| return 2; | |||||
| case NodeWarningType::Info: | |||||
| return 1; | |||||
| } | |||||
| BLI_assert(false); | |||||
| return 0; | |||||
| } | |||||
| static char *node_errrors_tooltip_fn(bContext *UNUSED(C), void *argN, const char *UNUSED(tip)) | |||||
| { | |||||
| char *message = static_cast<char *>(argN); | |||||
| return BLI_strdup(message); | |||||
| } | |||||
| #define NODE_HEADER_ICON_SIZE 0.8f * U.widget_unit | |||||
JacquesLucke: `(0.8f * U.widget_unit)` | |||||
| static const NodeUIStorage *node_ui_storage_get_from_context(const bContext *C, | |||||
| const bNodeTree &ntree, | |||||
| const bNode &node) | |||||
| { | |||||
| const NodeTreeUIStorage *node_tree_ui_storage = ntree.ui_storage; | |||||
| if (node_tree_ui_storage == nullptr) { | |||||
| return nullptr; | |||||
| } | |||||
| const Map<NodeUIStorageContextModifier, NodeUIStorage> *node_ui_storage = | |||||
| node_tree_ui_storage->node_map.lookup_ptr_as(StringRef(node.name)); | |||||
| if (node_ui_storage == nullptr) { | |||||
| return nullptr; | |||||
| } | |||||
| const Object *active_object = CTX_data_active_object(C); | |||||
| const ModifierData *active_modifier = BKE_object_active_modifier(active_object); | |||||
| if (active_object == nullptr || active_modifier == nullptr) { | |||||
| return nullptr; | |||||
| } | |||||
| const NodeUIStorageContextModifier context = NodeUIStorageContextModifier(*active_object, | |||||
| *active_modifier); | |||||
| return node_ui_storage->lookup_ptr(context); | |||||
| } | |||||
| static void node_add_error_message_button( | |||||
| const bContext *C, bNodeTree &ntree, bNode &node, const rctf &rect, float &icon_offset) | |||||
| { | |||||
| const NodeUIStorage *node_ui_storage = node_ui_storage_get_from_context(C, ntree, node); | |||||
| if (node_ui_storage == nullptr) { | |||||
| return; | |||||
| } | |||||
| /* The UI API forces us to allocate memory for each error message we pass. | |||||
Done Inline ActionsWanted to change "todo" to something else. JacquesLucke: Wanted to change "todo" to something else. | |||||
| * The ownership of #UI_but_func_tooltip_set's argument is transferred to the button. | |||||
| * We shouldn't need to do this though, investigate improving this. */ | |||||
| int total_str_len = node_ui_storage->warnings.size(); /* Leave room for new line characters. */ | |||||
| for (const NodeWarning &warning : node_ui_storage->warnings) { | |||||
| total_str_len += warning.message.size(); | |||||
| } | |||||
| char *tooltip_alloc = (char *)MEM_mallocN(sizeof(char) * total_str_len, __func__); | |||||
| int tooltip_offest = 0; | |||||
Done Inline Actionstypo JacquesLucke: typo | |||||
| for (const NodeWarning &warning : node_ui_storage->warnings) { | |||||
| BLI_strncpy(tooltip_alloc + tooltip_offest, warning.message.c_str(), warning.message.size()); | |||||
| tooltip_offest += warning.message.size(); | |||||
| BLI_strncpy(tooltip_alloc + tooltip_offest, "\n", 1); | |||||
| tooltip_offest++; | |||||
| } | |||||
| uint8_t highest_priority = 0; | |||||
| NodeWarningType highest_priority_type = NodeWarningType::Info; | |||||
| for (const NodeWarning &warning : node_ui_storage->warnings) { | |||||
| const uint8_t priority = node_error_type_priority(warning.type); | |||||
| if (priority > highest_priority) { | |||||
| highest_priority = priority; | |||||
| highest_priority_type = warning.type; | |||||
| } | |||||
| } | |||||
| icon_offset -= NODE_HEADER_ICON_SIZE; | |||||
| UI_block_emboss_set(node.block, UI_EMBOSS_NONE); | |||||
| uiBut *but = uiDefIconBut(node.block, | |||||
| UI_BTYPE_BUT, | |||||
| 0, | |||||
| node_error_type_to_icon(highest_priority_type), | |||||
| icon_offset, | |||||
| rect.ymax - NODE_DY, | |||||
| NODE_HEADER_ICON_SIZE, | |||||
| UI_UNIT_Y, | |||||
| nullptr, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| nullptr); | |||||
| UI_but_func_tooltip_set(but, node_errrors_tooltip_fn, tooltip_alloc); | |||||
| UI_block_emboss_set(node.block, UI_EMBOSS); | |||||
| } | |||||
| static void node_draw_basis(const bContext *C, | static void node_draw_basis(const bContext *C, | ||||
| const View2D *v2d, | const View2D *v2d, | ||||
| const SpaceNode *snode, | const SpaceNode *snode, | ||||
| bNodeTree *ntree, | bNodeTree *ntree, | ||||
| bNode *node, | bNode *node, | ||||
| bNodeInstanceKey key) | bNodeInstanceKey key) | ||||
| { | { | ||||
| /* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */ | /* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */ | ||||
| const float iconbutw = 0.8f * U.widget_unit; | const float iconbutw = NODE_HEADER_ICON_SIZE; | ||||
| /* skip if out of view */ | /* skip if out of view */ | ||||
| if (BLI_rctf_isect(&node->totr, &v2d->cur, nullptr) == false) { | if (BLI_rctf_isect(&node->totr, &v2d->cur, nullptr) == false) { | ||||
| UI_block_end(C, node->block); | UI_block_end(C, node->block); | ||||
| node->block = nullptr; | node->block = nullptr; | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | uiDefIconBut(node->block, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| ""); | ""); | ||||
| UI_block_emboss_set(node->block, UI_EMBOSS); | UI_block_emboss_set(node->block, UI_EMBOSS); | ||||
| } | } | ||||
| node_add_error_message_button(C, *ntree, *node, *rct, iconofs); | |||||
| /* title */ | /* title */ | ||||
| if (node->flag & SELECT) { | if (node->flag & SELECT) { | ||||
| UI_GetThemeColor4fv(TH_SELECT, color); | UI_GetThemeColor4fv(TH_SELECT, color); | ||||
| } | } | ||||
| else { | else { | ||||
| UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color); | UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 718 Lines • Show Last 20 Lines | |||||
(0.8f * U.widget_unit)