@@ -1045,26 +1045,21 @@ namespace minsky
10451045
10461046 }
10471047
1048- void Group::draw1edge (const vector<VariablePtr>& vars, cairo_t * cairo,
1049- float x) const
1048+ // Helper to compute edge variable layout (world-space positions) radially
1049+ static void layoutEdgeVariables (const vector<VariablePtr>& vars, float xEdge,
1050+ const Item* groupItem, double groupRotation)
10501051 {
10511052 float top=0 , bottom=0 ;
1052- const double angle=rotation () * M_PI / 180.0 ;
10531053 for (size_t i=0 ; i<vars.size (); ++i)
10541054 {
1055- const Rotate r (rotation () ,0 ,0 );
1055+ const Rotate r (groupRotation ,0 ,0 );
10561056 auto & v=vars[i];
1057- float y =0 ;
1057+ float yOff =0 ;
10581058 auto z=v->zoomFactor ();
10591059 auto t=v->bb .top ()*z, b=v->bb .bottom ()*z;
1060- if (i>0 ) y = i%2 ? top-b: bottom-t;
1061- v->moveTo (r.x (x,y)+this ->x (), r.y (x,y)+this ->y ());
1062- const cairo::CairoSave cs (cairo);
1063- cairo_translate (cairo,x,y);
1064- // cairo context is already rotated, so antirotate
1065- cairo_rotate (cairo,-angle);
1066- v->rotation (rotation ());
1067- v->draw (cairo);
1060+ if (i>0 ) yOff = i%2 ? top-b: bottom-t;
1061+ v->moveTo (r.x (xEdge,yOff)+groupItem->x (), r.y (xEdge,yOff)+groupItem->y ());
1062+ v->rotation (groupRotation);
10681063 if (i==0 )
10691064 {
10701065 bottom=b;
@@ -1077,6 +1072,44 @@ namespace minsky
10771072 }
10781073 }
10791074
1075+ void Group::draw1edge (const vector<VariablePtr>& vars, cairo_t * cairo,
1076+ float xEdge) const
1077+ {
1078+ layoutEdgeVariables (vars, xEdge, this , rotation ());
1079+
1080+ // Iterate again solely to perform drawing steps.
1081+ // Group::draw has ALREADY called cairo_scale(cairo, z, z), so the `xEdge`
1082+ // parameter is properly matched to the visual coordinates.
1083+ // However, translating `yOff` locally during rendering requires tracking
1084+ // the variable bounding boxes WITHOUT pre-multiplying `z` onto them here.
1085+ const double angle=rotation () * M_PI / 180.0 ;
1086+ float top=0 , bottom=0 ;
1087+ for (size_t i=0 ; i<vars.size (); ++i)
1088+ {
1089+ auto & v=vars[i];
1090+
1091+ float yOff = 0 ;
1092+ auto t = v->bb .top (), b = v->bb .bottom ();
1093+ if (i > 0 ) yOff = i % 2 ? top - b : bottom - t;
1094+
1095+ const cairo::CairoSave cs (cairo);
1096+ cairo_translate (cairo,xEdge,yOff);
1097+ // cairo context is already rotated, so antirotate
1098+ cairo_rotate (cairo,-angle);
1099+ v->draw (cairo);
1100+
1101+ if (i == 0 )
1102+ {
1103+ bottom = b;
1104+ top = t;
1105+ }
1106+ else if (i % 2 )
1107+ top -= v->height () / v->zoomFactor (); // Remove zoom as Group::draw supplies it
1108+ else
1109+ bottom += v->height () / v->zoomFactor ();
1110+ }
1111+ }
1112+
10801113 void Group::drawEdgeVariables (cairo_t * cairo) const
10811114 {
10821115 float left, right; margins (left,right);
@@ -1196,28 +1229,8 @@ namespace minsky
11961229 margins (leftMargin, rightMargin);
11971230 const float z = zoomFactor ();
11981231
1199- auto position1edge = [&](const std::vector<VariablePtr>& vars, float xEdge)
1200- {
1201- float top = 0 , bottom = 0 ;
1202- for (size_t i = 0 ; i < vars.size (); ++i)
1203- {
1204- const Rotate r (rotation (), 0 , 0 );
1205- auto & v = vars[i];
1206- float yOff = 0 ;
1207- auto vz = v->zoomFactor ();
1208- auto t = v->bb .top () * vz, b = v->bb .bottom () * vz;
1209- if (i > 0 ) yOff = (i % 2 ) ? top - b : bottom - t;
1210- v->moveTo (r.x (xEdge, yOff) + this ->x (),
1211- r.y (xEdge, yOff) + this ->y ());
1212- v->rotation (rotation ());
1213- if (i == 0 ) { bottom = b; top = t; }
1214- else if (i % 2 ) top -= v->height ();
1215- else bottom += v->height ();
1216- }
1217- };
1218-
1219- position1edge (inVariables, -0 .5f * (iWidth () * z - leftMargin));
1220- position1edge (outVariables, 0 .5f * (iWidth () * z - rightMargin));
1232+ layoutEdgeVariables (inVariables, -0 .5f * (iWidth () * z - leftMargin), this , rotation ());
1233+ layoutEdgeVariables (outVariables, 0 .5f * (iWidth () * z - rightMargin), this , rotation ());
12211234 }
12221235
12231236 ItemPtr Group::select (float x, float y) const
0 commit comments