157 lines
5.2 KiB
Dart
157 lines
5.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
class ScenarioSimulationItem {
|
|
const ScenarioSimulationItem({
|
|
required this.id,
|
|
required this.title,
|
|
required this.available,
|
|
required this.isActive,
|
|
required this.reason,
|
|
required this.help,
|
|
required this.onHelp,
|
|
required this.onActivate,
|
|
required this.onStop,
|
|
});
|
|
|
|
final String id;
|
|
final String title;
|
|
final bool available;
|
|
final bool isActive;
|
|
final String reason;
|
|
final String help;
|
|
final VoidCallback onHelp;
|
|
final VoidCallback onActivate;
|
|
final VoidCallback onStop;
|
|
}
|
|
|
|
class ScenarioSimulationWidget extends StatelessWidget {
|
|
const ScenarioSimulationWidget({
|
|
super.key,
|
|
required this.visible,
|
|
required this.panelWidth,
|
|
required this.panelHeight,
|
|
required this.scenarios,
|
|
required this.onHide,
|
|
required this.onShow,
|
|
});
|
|
|
|
final bool visible;
|
|
final double panelWidth;
|
|
final double panelHeight;
|
|
final List<ScenarioSimulationItem> scenarios;
|
|
final VoidCallback onHide;
|
|
final VoidCallback onShow;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final cs = Theme.of(context).colorScheme;
|
|
if (!visible) {
|
|
return Positioned(
|
|
right: 8,
|
|
bottom: 8,
|
|
child: FilledButton.icon(
|
|
onPressed: onShow,
|
|
icon: const Icon(Icons.playlist_add_check),
|
|
label: const Text('Сценарии'),
|
|
),
|
|
);
|
|
}
|
|
|
|
return Positioned(
|
|
right: 8,
|
|
bottom: 8,
|
|
child: Container(
|
|
width: panelWidth,
|
|
height: panelHeight,
|
|
padding: const EdgeInsets.all(10),
|
|
decoration: BoxDecoration(
|
|
color: cs.surface.withValues(alpha: 0.92),
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(color: cs.outlineVariant),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
const Expanded(
|
|
child: Text(
|
|
'Сценарии',
|
|
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700),
|
|
),
|
|
),
|
|
IconButton(
|
|
tooltip: 'Скрыть панель',
|
|
onPressed: onHide,
|
|
icon: const Icon(Icons.visibility_off_outlined),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
Expanded(
|
|
child: ListView(
|
|
children: scenarios
|
|
.map(
|
|
(scenario) => Padding(
|
|
padding: const EdgeInsets.only(bottom: 8),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
scenario.title,
|
|
style: const TextStyle(fontWeight: FontWeight.w600),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
scenario.reason,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: scenario.isActive
|
|
? cs.primary
|
|
: scenario.available
|
|
? Colors.green.shade700
|
|
: cs.error,
|
|
),
|
|
),
|
|
const SizedBox(height: 6),
|
|
Wrap(
|
|
spacing: 8,
|
|
runSpacing: 6,
|
|
children: [
|
|
OutlinedButton.icon(
|
|
onPressed: scenario.onHelp,
|
|
icon: const Icon(Icons.help_outline, size: 18),
|
|
label: const Text('Help'),
|
|
),
|
|
if (scenario.isActive)
|
|
FilledButton.icon(
|
|
style: FilledButton.styleFrom(
|
|
backgroundColor: cs.error,
|
|
),
|
|
onPressed: scenario.onStop,
|
|
icon: const Icon(Icons.stop_circle_outlined),
|
|
label: const Text('Остановить'),
|
|
)
|
|
else
|
|
FilledButton(
|
|
onPressed: scenario.available
|
|
? scenario.onActivate
|
|
: null,
|
|
child: const Text('Активировать'),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
)
|
|
.toList(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|