handleExpandChild method
Handle expanding a specific child by name for search navigation.
Partially reveals only childName inside nodeId (plus its
connecting hyperedges). Used by the search routine to walk the
hierarchy without fully expanding every level.
Implementation
Future<SchematicLayoutResult?> handleExpandChild(
String nodeId,
String childName,
) async {
if (isToggling) {
return null;
}
final engine = _layoutEngine;
if (engine == null || schematicAdapter == null) {
return null;
}
setState(() {
isToggling = true;
togglingLabel = 'Expanding...';
pendingToggleNodeId = nodeId;
});
// Let the spinner appear before heavy processing.
final completer = Completer<void>();
WidgetsBinding.instance.addPostFrameCallback((_) {
completer.complete();
});
await completer.future;
SchedulerBinding.instance.ensureVisualUpdate();
try {
final expanded = schematicAdapter!.expandChild(nodeId, childName);
if (!expanded) {
if (mounted) {
setState(() {
isToggling = false;
pendingToggleNodeId = null;
});
}
return null;
}
final elkGraph = schematicAdapter!.schematic.toJsGraph();
final newLayout = await engine.computeLayoutFromElkGraph(
elkGraph,
sessionId: _sessionId,
);
if (newLayout.hasError || !mounted) {
if (mounted) {
setState(() {
isToggling = false;
pendingToggleNodeId = null;
});
}
return null;
}
setState(() {
layout = newLayout;
isToggling = false;
pendingToggleNodeId = null;
focusPortId = null;
recentlyToggledNodeId = nodeId;
});
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
setState(() {
recentlyToggledNodeId = null;
});
}
});
return newLayout;
} on Exception {
if (mounted) {
setState(() {
isToggling = false;
pendingToggleNodeId = null;
});
}
return null;
}
}