buildInspectorPanel function

Widget buildInspectorPanel(
  1. String? exportMessage,
  2. TraceSpan? hoveredSpan,
  3. TimeDisplayMode timeDisplayMode,
  4. int? baseTime,
)

Implementation

Widget buildInspectorPanel(
  String? exportMessage,
  TraceSpan? hoveredSpan,
  TimeDisplayMode timeDisplayMode,
  int? baseTime,
) {
  return LayoutBuilder(
    builder: (context, constraints) {
      final maxWidth = constraints.maxWidth;

      Widget contentWidget;
      int contentHeight = 1;

      if (exportMessage != null) {
        contentWidget = Text(
          exportMessage,
          style: const Style(foreground: Color(100, 255, 100)),
        );
      } else if (hoveredSpan == null) {
        contentWidget = Text(
          'No event hovered. Hover over a span to inspect details.',
          style: const Style(foreground: Colors.white),
        );
      } else {
        final span = hoveredSpan;
        final durMs = (span.endUs - span.startUs) / 1000.0;
        final startMs = span.startUs / 1000.0;
        final endMs = span.endUs / 1000.0;

        final lines = <String>[];

        String titleLine = '[Hovered] ${span.displayLabel}';
        if (titleLine.length > maxWidth - 2) {
          titleLine = '${titleLine.substring(0, maxWidth - 5)}...';
        }
        lines.add(titleLine);

        var timingLine = switch (timeDisplayMode) {
          TimeDisplayMode.formatted =>
            'Start: ${formatDuration(startMs)}  |  End: ${formatDuration(endMs)}  |  Duration: ${formatDuration(durMs)}',
          TimeDisplayMode.rawRelative =>
            'Start: ${span.startUs}  |  End: ${span.endUs}  |  Duration: ${formatDuration(durMs)}',
          TimeDisplayMode.rawAbsolute =>
            'Start: ${span.startUs + (baseTime ?? 0)}  |  End: ${span.endUs + (baseTime ?? 0)}  |  Duration: ${formatDuration(durMs)}',
        };
        if (timingLine.length > maxWidth - 2) {
          timingLine = '${timingLine.substring(0, maxWidth - 5)}...';
        }
        lines.add(timingLine);

        if (span.args.isNotEmpty) {
          lines.add('Args:');
          for (final entry in span.args.entries) {
            final argStr = '  ${entry.key}: ${entry.value}';
            lines.addAll(wrapTraceText(argStr, maxWidth - 2));
          }
        }

        final totalLines = lines.length;
        contentHeight = min(totalLines, 12);

        contentWidget = ListView.fromStrings(
          lines,
          itemStyle: const Style(foreground: Colors.white),
          selectedStyle: const Style(foreground: Colors.white),
          showScrollbar: totalLines > contentHeight,
        );
      }

      return SizedBox(
        height: contentHeight + 2,
        child: DecoratedBox(
          decoration: const BoxDecoration(
            border: Border(
              topChar: '─',
              bottomChar: '─',
              leftChar: '│',
              rightChar: '│',
              topLeftChar: '├',
              topRightChar: '┤',
              bottomLeftChar: '└',
              bottomRightChar: '┘',
              style: Style(foreground: Color(120, 120, 120)),
            ),
            backgroundColor: Color(30, 30, 30),
          ),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 1, vertical: 0),
            child: contentWidget,
          ),
        ),
      );
    },
  );
}