@@ -283,13 +283,12 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name,
283283
284284 // Is the node out of sight on canvas ?
285285 bool isNodeVisible = ImGui::IsRectVisible ( curNodeData.outerContentBox .Min , curNodeData.outerContentBox .Max );
286- if ( !isNodeVisible ){
287- curNodeData.zoomName = ImGuiExNodeZoom_Invisible;
288- return false ;
289- }
290286
291287 // Calc zoom name
292- {
288+ if ( !isNodeVisible ){
289+ curNodeData.zoomName = ImGuiExNodeZoom_Invisible;
290+ // return false;
291+ }else {
293292 unsigned int curWidth = curNodeData.outerContentBox .GetSize ().x ;
294293 if ( curWidth < IMGUI_EX_NODE_MIN_WIDTH_SMALL )
295294 curNodeData.zoomName = ImGuiExNodeZoom_Imploded;
@@ -303,7 +302,7 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name,
303302 curNodeData.viewName = ImGuiExNodeView_None;
304303
305304 // Adapt the layout for pins
306- int pinsWidth = 0 ;
305+ static int pinsWidth; pinsWidth = 0 ;
307306 /* if(curNodeData.zoomName == ImGuiExNodeZoom_Imploded){
308307 // Behaviour: if there are any pins, show only pins. Else imploded still have small content.
309308 pinsWidth = 0;
@@ -351,6 +350,11 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name,
351350 fg->AddRect (curNodeData.outerContentBox .Min , ImVec2 (curNodeData.outerContentBox .Max .x ,curNodeData.outerContentBox .Min .y +IMGUI_EX_NODE_HEADER_HEIGHT), IM_COL32 (255 ,255 ,255 ,200 ));
352351 fg->AddRect (ImVec2 (curNodeData.outerContentBox .Min .x , curNodeData.outerContentBox .Max .y -IMGUI_EX_NODE_FOOTER_HEIGHT), curNodeData.outerContentBox .Max , IM_COL32 (255 ,255 ,255 ,200 ));
353352#endif
353+ // Return early now that everything has been calc'd.
354+ if ( !isNodeVisible ){
355+ nodeDrawList = ImGui::GetWindowDrawList (); // So that nodes can still draw pins !
356+ return false ;
357+ }
354358 // Create node window
355359 ImGui::PushStyleVar (ImGuiStyleVar_WindowPadding, ImVec2 (0 ,0 ));// IMGUI_EX_NODE_CONTENT_PADDING,IMGUI_EX_NODE_CONTENT_PADDING));
356360 ImGui::SetNextWindowPos (curNodeData.outerContentBox .Min );
@@ -422,24 +426,24 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name,
422426 // Enable drag on title
423427 // unsigned int curTabsWidth = (curNodeData.zoomName > ImGuiExNodeZoom_Imploded) ? IMGUI_EX_NODE_HEADER_TOOLBAR_WIDTH : 0;
424428 ImGui::SetCursorScreenPos ( curNodeData.outerContentBox .Min );
425- // ImGui::InvisibleButton( "headerGripBtn", ImVec2( curNodeData.outerContentBox.GetSize().x-curTabsWidth , IMGUI_EX_NODE_HEADER_HEIGHT ) );
426- ImGui::InvisibleButton ( " headerGripBtn" , ImVec2 ( curNodeData.outerContentBox .GetSize ().x -IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor, IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor ) );
429+ // ImGui::InvisibleButton( "headerGripBtn", ImVec2( curNodeData.outerContentBox.GetSize().x-IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor , IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor ) );
430+ ImGui::InvisibleButton ( " headerGripBtn" , ImMax ( ImVec2 ( curNodeData.outerContentBox .GetSize ().x -IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor, IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor ), ImVec2 ( 1 , 1 ) ) );
427431 static ImVec2 mouseOffset (0 ,0 );
428432 static bool isDraggingHeader = false ;
429433
430- if (ImGui::IsItemActive () && ImGui::IsItemClicked (0 )){
434+ if (ImGui::IsItemActive () && ImGui::IsItemClicked (ImGuiMouseButton_Left )){
431435 activeNode = nId;
432436 if (ImGui::GetIO ().KeyShift && name != " audio device" ){
433437 selected_nodes.push_back (nId);
434438 }
435439 }
436440
437441 // deselect nodes on clicking on patch
438- if (ImGui::IsMouseClicked (0 ) && !isAnyCanvasNodeHovered){
442+ if (ImGui::IsMouseClicked (ImGuiMouseButton_Left ) && !isAnyCanvasNodeHovered){
439443 selected_nodes.clear ();
440444 }
441445
442- if (ImGui::IsItemActive () && ImGui::IsMouseDragging (0 )){
446+ if (ImGui::IsItemActive () && ImGui::IsMouseDragging (ImGuiMouseButton_Left )){
443447 if (!isDraggingHeader){
444448 mouseOffset = ImGui::GetMousePos ()-curNodeData.outerContentBox .Min ;
445449 isDraggingHeader = true ;
@@ -535,18 +539,19 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name,
535539
536540 }
537541
542+ // reset origin
543+ ImGui::SetCursorScreenPos ( curNodeData.innerContentBox .Min );
544+
538545 // Return before drawing content, if scale is too small ?
539546 // todo. (This is already partially handled by BeginNodeContent();)
540- if ( false && curNodeData.zoomName < ImGuiExNodeZoom_Small ){
547+ if ( curNodeData.zoomName <= ImGuiExNodeZoom_Imploded ){
541548 // Fill empty space with color
542549 // canvasDrawList->AddRectFilled(); // todo
543550
544551 // Todo: something with : window->SkipItems to prevent drawing to node ?
545552 return false ;
546553 }
547554
548- // reset origin
549- ImGui::SetCursorScreenPos ( curNodeData.innerContentBox .Min );
550555
551556 // The combination of a cliprect and columns allows us to set a clipping space for node widgets while reserving drawable space for pins, without having to add an extra window / childframe.
552557 ImGui::PushClipRect ( curNodeData.leftPins .region .Min , curNodeData.rightPins .region .Max , true ); // Inner space + Node Spaces
@@ -557,9 +562,10 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name,
557562 | ImGuiColumnsFlags_NoForceWithinWindow // important so there's no weird auto adjustments.
558563 );
559564 // Column layout
565+ // Note: A column of 0 width will probably cause crashes
560566 ImGui::SetColumnOffset (0 ,0 );
561- ImGui::SetColumnOffset (1 ,curNodeData.leftPins .region .GetSize ().x );
562- ImGui::SetColumnOffset (2 ,curNodeData.innerContentBox .Max .x -curNodeData.leftPins .region .Min .x );
567+ ImGui::SetColumnOffset (1 , std::max ( curNodeData.leftPins .region .GetSize ().x , 1 . f ) );
568+ ImGui::SetColumnOffset (2 , std::max ( curNodeData.innerContentBox .Max .x -curNodeData.leftPins .region .Min .x , 2 . f ) );
563569
564570 // move to middle column where the user can draw
565571 ImGui::NextColumn ();
@@ -580,7 +586,7 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name,
580586
581587 // Draw default menu items
582588 if (ImGui::BeginPopup (IMGUI_EX_NODE_MENU_ID)){
583- if (name != " audio device" ){
589+ if (name != " audio device" ){ // Todo: should not be checked on title... maybe: if(node->canBeRemoved())
584590 if (ImGui::MenuItem (" Delete" )) curNodeData.menuActions |= ImGuiExNodeMenuActionFlags_DeleteNode;
585591 // if(ImGui::MenuItem("Copy")) curNodeData.menuActions |= ImGuiExNodeMenuActionFlags_CopyNode;
586592 if (ImGui::MenuItem (" Duplicate" )) curNodeData.menuActions |= ImGuiExNodeMenuActionFlags_DuplicateNode;
@@ -699,6 +705,7 @@ ImGuiEx::NodeConnectData ImGuiEx::NodeCanvas::AddNodePin( const int nodeID, cons
699705 static int linkID = -1 ;
700706
701707 // Check ImGui Callstack
708+ IM_ASSERT (nodeDrawList != NULL ); // Huh ?
702709 IM_ASSERT (isDrawingCanvas == true ); // Please Call between Begin() and End()
703710 IM_ASSERT (isDrawingNode == true ); // Please Call between BeginNode() and EndNode()
704711 IM_ASSERT (_pinFlag == ImGuiExNodePinsFlags_Left || _pinFlag == ImGuiExNodePinsFlags_Right); // Only left / right pins can be created
@@ -713,8 +720,8 @@ ImGuiEx::NodeConnectData ImGuiEx::NodeCanvas::AddNodePin( const int nodeID, cons
713720 ImGui::NextColumn (); // right col
714721 if ( _pinFlag==ImGuiExNodePinsFlags_Left ) ImGui::NextColumn (); // left column
715722
716- // Hover interaction
717- if (pinLayout.pinSpace .x > 0 ){
723+ // Draw pins
724+ if (pinLayout.pinSpace .x > 1 ){ // Minimum width (with ±0 values ImGui crashes)
718725 if ( _pinFlag==ImGuiExNodePinsFlags_Left ){
719726 ImGui::SetCursorScreenPos ( pinLayout.curDrawPos );
720727 }
@@ -855,40 +862,40 @@ ImGuiEx::NodeConnectData ImGuiEx::NodeCanvas::AddNodePin( const int nodeID, cons
855862 // float pinSpace = (ImGui::IsItemHovered()) ? IMGUI_EX_NODE_PIN_WIDTH_HOVERED : IMGUI_EX_NODE_PIN_WIDTH;
856863 float pinSpace = IMGUI_EX_NODE_PIN_WIDTH*scaleFactor;
857864
858- // Draw pin
859-
860865 // Left side (INLETS)
861866 if ( _pinFlag==ImGuiExNodePinsFlags_Left ){
862-
867+ // Update pin position
863868 inletPinsPositions[nodeID][pinID] = pinLayout.curDrawPos + ImVec2 ( IMGUI_EX_NODE_PIN_WIDTH*scaleFactor * .5f , pinLayout.pinSpace .y * .5f ) + ImVec2 (IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,0 );
864869
865- nodeDrawList->AddCircleFilled (inletPinsPositions[nodeID][pinID], pinSpace * .5f , _color, 6 );
870+ // Draw pin
871+ if ( curNodeData.zoomName != ImGuiExNodeZoom_Invisible ){
872+ nodeDrawList->AddCircleFilled (inletPinsPositions[nodeID][pinID], pinSpace * .5f , _color, 6 );
873+
874+ if (ImGui::GetMousePos ().x > inletPinsPositions[nodeID][pinID].x -(pinLayout.pinSpace .x *.5f ) && ImGui::GetMousePos ().x < inletPinsPositions[nodeID][pinID].x +(pinLayout.pinSpace .x *.5f ) && ImGui::GetMousePos ().y > inletPinsPositions[nodeID][pinID].y -(pinLayout.pinSpace .y *.5f ) && ImGui::GetMousePos ().y < inletPinsPositions[nodeID][pinID].y +(pinLayout.pinSpace .y *.5f )){
875+ if (activePinType == _type || activePinType == " " ){
876+ nodeDrawList->AddCircle (inletPinsPositions[nodeID][pinID],pinSpace * 0 .9f , _color, 6 );
877+ ImVec2 tempPos = inletPinsPositions[nodeID][pinID] - ImVec2 (pinSpace * .5f + (IMGUI_EX_NODE_PIN_WIDTH + 6 )*scaleFactor,ImGui::GetTextLineHeight ()*-.4f ) - ImGui::CalcTextSize (_label);
878+ canvasDrawList->AddRectFilled (tempPos + ImVec2 (-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),tempPos + ImGui::CalcTextSize (_label) + ImVec2 (IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),IM_COL32 (40 ,40 ,40 ,180 ) );
879+ canvasDrawList->AddText ( tempPos, _color, _label);
880+ }
866881
867- if (ImGui::GetMousePos ().x > inletPinsPositions[nodeID][pinID].x -(pinLayout.pinSpace .x *.5f ) && ImGui::GetMousePos ().x < inletPinsPositions[nodeID][pinID].x +(pinLayout.pinSpace .x *.5f ) && ImGui::GetMousePos ().y > inletPinsPositions[nodeID][pinID].y -(pinLayout.pinSpace .y *.5f ) && ImGui::GetMousePos ().y < inletPinsPositions[nodeID][pinID].y +(pinLayout.pinSpace .y *.5f )){
868- if (activePinType == _type || activePinType == " " ){
869- nodeDrawList->AddCircle (inletPinsPositions[nodeID][pinID],pinSpace * 0 .9f , _color, 6 );
870- ImVec2 tempPos = inletPinsPositions[nodeID][pinID] - ImVec2 (pinSpace * .5f + (IMGUI_EX_NODE_PIN_WIDTH + 6 )*scaleFactor,ImGui::GetTextLineHeight ()*-.4f ) - ImGui::CalcTextSize (_label);
871- canvasDrawList->AddRectFilled (tempPos + ImVec2 (-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),tempPos + ImGui::CalcTextSize (_label) + ImVec2 (IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),IM_COL32 (40 ,40 ,40 ,180 ) );
872- canvasDrawList->AddText ( tempPos, _color, _label);
873882 }
874883
875- }
884+ if (_connected){
885+ nodeDrawList->AddCircle (inletPinsPositions[nodeID][pinID],pinSpace * 0 .9f , _color, 6 );
886+ }
876887
877- if (_connected){
878- nodeDrawList->AddCircle (inletPinsPositions[nodeID][pinID],pinSpace * 0 .9f , _color, 6 );
879888 }
880889
881890 }
882891
883892 // right side (OUTLETS)
884893 else if ( _pinFlag==ImGuiExNodePinsFlags_Right ){
885-
894+ // Update pin position
886895 outletPinsPositions[nodeID][pinID] = pinLayout.curDrawPos + ImVec2 ( IMGUI_EX_NODE_PIN_WIDTH*scaleFactor * -.5f , pinLayout.pinSpace .y * .5f );
887896
888- nodeDrawList->AddCircleFilled (outletPinsPositions[nodeID][pinID], pinSpace * .5f , _color, 6 );
889-
890897 // draw links (OUTLETS to INLETS ONLY)
891- for (int i=0 ;i<_linksData.size ();i++){
898+ for (unsigned int i=0 ;i<_linksData.size ();i++){
892899 const LinkBezierData link_data = get_link_renderable (outletPinsPositions[nodeID][pinID], canvasView.translation +(_linksData.at (i)._toPinPosition *canvasView.scale ), IMGUI_EX_NODE_LINK_LINE_SEGMENTS_PER_LENGTH);
893900
894901 const bool is_hovered = is_mouse_hovering_near_link (link_data.bezier );
@@ -907,25 +914,31 @@ ImGuiEx::NodeConnectData ImGuiEx::NodeCanvas::AddNodePin( const int nodeID, cons
907914 }
908915
909916
910- ImU32 _tempColor = _color;
917+ static ImU32 _tempColor;
918+ _tempColor = _color;
911919 if (std::find (selected_links.begin (), selected_links.end (),_linksData.at (i)._linkID )!=selected_links.end ()){ // selected
912920 _tempColor = IM_COL32 (255 ,0 ,0 ,255 );
913921 }
914922
915923 canvasDrawList->AddBezierCurve (link_data.bezier .p0 , link_data.bezier .p1 , link_data.bezier .p2 , link_data.bezier .p3 , _tempColor, IMGUI_EX_NODE_LINK_THICKNESS, link_data.num_segments );
916924 }
917925
918- // draw labels
919- if (ImGui::GetMousePos ().x > outletPinsPositions[nodeID][pinID].x -IMGUI_EX_NODE_PIN_WIDTH_HOVERED && ImGui::GetMousePos ().x < outletPinsPositions[nodeID][pinID].x +IMGUI_EX_NODE_PIN_WIDTH_HOVERED && ImGui::GetMousePos ().y > outletPinsPositions[nodeID][pinID].y -IMGUI_EX_NODE_PIN_WIDTH_HOVERED && ImGui::GetMousePos ().y < outletPinsPositions[nodeID][pinID].y +IMGUI_EX_NODE_PIN_WIDTH_HOVERED){
920- if (connectType == 0 ){
921- nodeDrawList->AddCircle (outletPinsPositions[nodeID][pinID],pinSpace * 0 .9f , _color, 6 );
922- ImVec2 tempPos = outletPinsPositions[nodeID][pinID] + ImVec2 (pinSpace * .5f + 6 ,ImGui::GetTextLineHeight ()*-.5f );
923- canvasDrawList->AddRectFilled (tempPos + ImVec2 (-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),tempPos + ImGui::CalcTextSize (_label) + ImVec2 (IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),IM_COL32 (40 ,40 ,40 ,180 ) );
924- canvasDrawList->AddText ( tempPos, _color, _label);
926+ // Draw pin
927+ if ( curNodeData.zoomName != ImGuiExNodeZoom_Invisible ){
928+ nodeDrawList->AddCircleFilled (outletPinsPositions[nodeID][pinID], pinSpace * .5f , _color, 6 );
929+
930+ // draw labels
931+ if (ImGui::GetMousePos ().x > outletPinsPositions[nodeID][pinID].x -IMGUI_EX_NODE_PIN_WIDTH_HOVERED && ImGui::GetMousePos ().x < outletPinsPositions[nodeID][pinID].x +IMGUI_EX_NODE_PIN_WIDTH_HOVERED && ImGui::GetMousePos ().y > outletPinsPositions[nodeID][pinID].y -IMGUI_EX_NODE_PIN_WIDTH_HOVERED && ImGui::GetMousePos ().y < outletPinsPositions[nodeID][pinID].y +IMGUI_EX_NODE_PIN_WIDTH_HOVERED){
932+ if (connectType == 0 ){
933+ nodeDrawList->AddCircle (outletPinsPositions[nodeID][pinID],pinSpace * 0 .9f , _color, 6 );
934+ ImVec2 tempPos = outletPinsPositions[nodeID][pinID] + ImVec2 (pinSpace * .5f + 6 ,ImGui::GetTextLineHeight ()*-.5f );
935+ canvasDrawList->AddRectFilled (tempPos + ImVec2 (-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,-IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),tempPos + ImGui::CalcTextSize (_label) + ImVec2 (IMGUI_EX_NODE_PIN_WIDTH*scaleFactor,IMGUI_EX_NODE_PIN_WIDTH*scaleFactor),IM_COL32 (40 ,40 ,40 ,180 ) );
936+ canvasDrawList->AddText ( tempPos, _color, _label);
937+ }
925938 }
926939 }
927940
928- // draw pin connected
941+ // Draw Connected Appearance
929942 if (_connected){
930943 nodeDrawList->AddCircle (outletPinsPositions[nodeID][pinID],pinSpace * 0 .9f , _color, 6 );
931944 }
0 commit comments