buildSchematicCanvas method
Build the schematic canvas with theme support.
Implementation
Widget buildSchematicCanvas({Color? backgroundColor, Key? canvasKey}) {
if (layout == null) {
return const SizedBox.shrink();
}
return BlocBuilder<SchematicThemeCubit, SchematicThemeMode>(
builder: (context, themeMode) {
final isDarkMode = themeMode == SchematicThemeMode.dark;
final spinnerColor = isDarkMode ? Colors.white : Colors.black87;
final textColor = isDarkMode ? Colors.white : Colors.black87;
final canvas = SchematicCanvas(
key: canvasKey,
layout: layout!,
netlistJson: schematicJson,
externalHierarchy: externalHierarchy,
colorScheme: isDarkMode
? SchematicColorScheme.dark
: SchematicColorScheme.light,
onNodeToggle: handleNodeToggle,
onPortExpand: handlePortExpand,
onPortExpandThrough: handlePortExpandThrough,
onPortCollapse: handlePortCollapse,
onPortCollapseThrough: handlePortCollapseThrough,
onCollapsePartial: handleCollapsePartial,
onExpandNonPrimitives: handleExpandNonPrimitives,
onConvertToBlocksOnly: handleConvertToBlocksOnly,
onNodeToggleRecursive: handleNodeToggleRecursive,
onExpandNonPrimitivesRecursive: handleExpandNonPrimitivesRecursive,
onConvertToBlocksOnlyRecursive: handleConvertToBlocksOnlyRecursive,
onExpandChild: handleExpandChild,
onExpandWire: handleExpandWire,
onExpandPath: handleExpandPath,
signalNameForPort: (nodeId, portId) =>
schematicAdapter?.schematic.signalNameForPort(nodeId, portId),
directDriverSignalPath: (wireName, scopePath) => schematicAdapter
?.schematic
.directDriverSignalPath(wireName, scopePath),
pendingToggleNodeId: pendingToggleNodeId,
recentlyToggledNodeId: recentlyToggledNodeId,
focusPortId: focusPortId,
isDimmed: isToggling,
signalValueLookup: signalValueLookup,
onSendSignals: onSendSignals,
hasExternalSignalListeners: hasExternalSignalListeners,
onGoToSource: onGoToSource,
availableSourceFormats: availableSourceFormats,
incomingSignalPaths: incomingSignalPaths,
);
// Build the loading overlay — a small non-blocking corner badge
// so the schematic stays visible while the layout recomputes.
Widget buildLoadingOverlay() => Positioned(
top: 8,
right: 8,
child: Material(
color: Colors.transparent,
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: isDarkMode
? Colors.black.withValues(alpha: 0.65)
: Colors.white.withValues(alpha: 0.85),
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.black26,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 14,
height: 14,
child: CircularProgressIndicator(
color: spinnerColor,
strokeWidth: 2,
),
),
const SizedBox(width: 8),
Text(
togglingLabel,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: textColor,
fontWeight: FontWeight.w500,
),
),
],
),
),
),
);
// Wrap in container with optional background color
if (backgroundColor != null) {
return ColoredBox(
color: backgroundColor,
child: Stack(
children: [canvas, if (isToggling) buildLoadingOverlay()],
),
);
}
// Return canvas with loading overlay
return Stack(children: [canvas, if (isToggling) buildLoadingOverlay()]);
},
);
}