part of 'view.dart'; extension on _ServerDetailPageState { void _onTapNvidiaGpuItem(NvidiaSmiItem item) { final processes = item.memory.processes; final displayCount = processes.length > 5 ? 5 : processes.length; final height = displayCount * 47.0; context.showRoundDialog( title: item.name, child: SizedBox( width: double.maxFinite, height: height, child: ListView.builder( itemCount: processes.length, itemBuilder: (_, idx) => _buildGpuProcessItem(processes[idx]), ), ), actions: Btnx.oks, ); } void _onTapAmdGpuItem(AmdSmiItem item) { final processes = item.memory.processes; final displayCount = processes.length > 5 ? 5 : processes.length; final height = displayCount * 47.0; context.showRoundDialog( title: item.name, child: SizedBox( width: double.maxFinite, height: height, child: ListView.builder( itemCount: processes.length, itemBuilder: (_, idx) => _buildAmdGpuProcessItem(processes[idx]), ), ), actions: Btnx.oks, ); } void _onTapGpuProcessItem(NvidiaSmiMemProcess process) { context.showRoundDialog( title: '${process.pid}', titleMaxLines: 1, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ UIs.height13, Text('Memory: ${process.memory} MiB'), UIs.height13, Text('Process: ${process.name}'), ], ), actions: [TextButton(onPressed: () => context.pop(), child: Text(libL10n.close))], ); } void _onTapAmdGpuProcessItem(AmdSmiMemProcess process) { context.showRoundDialog( title: '${process.pid}', titleMaxLines: 1, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ UIs.height13, Text('Memory: ${process.memory} ${process.memory > 1024 ? 'MB' : 'KB'}'), UIs.height13, Text('Process: ${process.name}'), ], ), actions: [TextButton(onPressed: () => context.pop(), child: Text(libL10n.close))], ); } void _onTapCustomItem(MapEntry cmd) { context.showRoundDialog( title: cmd.key, child: SingleChildScrollView(child: Text(cmd.value, style: UIs.text13Grey)), actions: [TextButton(onPressed: () => context.pop(), child: Text(libL10n.close))], ); } void _onTapSensorItem(SensorItem si) { context.showRoundDialog( title: si.device, child: SingleChildScrollView( child: SimpleMarkdown( data: si.toMarkdown, styleSheet: MarkdownStyleSheet( tableBorder: TableBorder.all(color: Colors.grey), tableHead: const TextStyle(fontWeight: FontWeight.bold), ), ), ), ); } void _onTapTemperatureItem(String key) { Pfs.copy(key); context.showSnackBar('${libL10n.copy} ${libL10n.success}'); } bool _getInitExpand(int len, [int? max]) { if (!_collapse) return true; if (_size.width > UIs.columnWidth) return true; return len > 0 && len <= (max ?? 3); } } enum _NetSortType { device, trans, recv; bool get isDevice => this == _NetSortType.device; bool get isIn => this == _NetSortType.recv; bool get isOut => this == _NetSortType.trans; _NetSortType get next { switch (this) { case device: return trans; case _NetSortType.trans: return recv; case recv: return device; } } int Function(String, String) getSortFunc(NetSpeed ns) { switch (this) { case _NetSortType.device: return (b, a) => a.compareTo(b); case _NetSortType.recv: return (b, a) => ns.speedInBytes(ns.deviceIdx(a)).compareTo(ns.speedInBytes(ns.deviceIdx(b))); case _NetSortType.trans: return (b, a) => ns.speedOutBytes(ns.deviceIdx(a)).compareTo(ns.speedOutBytes(ns.deviceIdx(b))); } } } Widget _buildLineChart( List> spots, { String? tooltipPrefix, bool curve = false, int verticalInterval = 20, }) { return LineChart( LineChartData( lineTouchData: LineTouchData( touchTooltipData: LineTouchTooltipData( tooltipPadding: const EdgeInsets.all(5), tooltipBorderRadius: BorderRadius.circular(8), getTooltipItems: (List touchedSpots) { return touchedSpots.map((e) { return LineTooltipItem( '$tooltipPrefix${e.barIndex}: ${e.y.toStringAsFixed(2)}', const TextStyle(fontSize: 12, fontWeight: FontWeight.bold), ); }).toList(); }, ), handleBuiltInTouches: true, ), gridData: FlGridData( show: true, drawVerticalLine: false, horizontalInterval: verticalInterval.toDouble(), getDrawingHorizontalLine: (value) { return const FlLine(color: Color.fromARGB(43, 88, 91, 94), strokeWidth: 1); }, ), titlesData: FlTitlesData( show: true, rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), bottomTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, interval: 20, getTitlesWidget: (val, meta) { if (val % verticalInterval != 0) return UIs.placeholder; if (val == 0) return const Text('0 %', style: UIs.text12Grey); return Text(val.toInt().toString(), style: UIs.text12Grey); }, reservedSize: 27, ), ), ), borderData: FlBorderData(show: false), minY: -1, maxY: 101, lineBarsData: spots .map( (e) => LineChartBarData( spots: e, isCurved: curve, barWidth: 2, isStrokeCapRound: true, color: UIs.primaryColor, dotData: const FlDotData(show: false), belowBarData: BarAreaData(show: false), ), ) .toList(), ), ); }