focus-flow/apps/focus_flow_flutter/lib/widgets/timeline/difficulty_bars.dart

96 lines
2.6 KiB
Dart

/// Renders Difficulty Bars pieces for the FocusFlow Flutter timeline.
library;
import 'package:flutter/material.dart';
import 'package:scheduler_core/scheduler_core.dart';
import '../../theme/focus_flow_tokens.dart';
class DifficultyBars extends StatelessWidget {
const DifficultyBars({
required this.difficulty,
this.color = FocusFlowTokens.restPurple,
this.size = const Size(54, 34),
super.key,
});
final TimelineDifficultyIconToken difficulty;
final Color color;
final Size size;
static int fillCount(TimelineDifficultyIconToken difficulty) {
return switch (difficulty) {
TimelineDifficultyIconToken.notSet => 0,
TimelineDifficultyIconToken.veryEasy => 1,
TimelineDifficultyIconToken.easy => 2,
TimelineDifficultyIconToken.medium => 3,
TimelineDifficultyIconToken.hard => 4,
TimelineDifficultyIconToken.veryHard => 5,
};
}
static int fillCountForLevel(DifficultyLevel difficulty) {
return switch (difficulty) {
DifficultyLevel.notSet => 0,
DifficultyLevel.veryEasy => 1,
DifficultyLevel.easy => 2,
DifficultyLevel.medium => 3,
DifficultyLevel.hard => 4,
DifficultyLevel.veryHard => 5,
};
}
@override
Widget build(BuildContext context) {
return CustomPaint(
size: size,
painter: _DifficultyBarsPainter(
filledCount: fillCount(difficulty),
color: color,
),
);
}
}
class _DifficultyBarsPainter extends CustomPainter {
const _DifficultyBarsPainter({
required this.filledCount,
required this.color,
});
final int filledCount;
final Color color;
@override
void paint(Canvas canvas, Size size) {
final gap = size.width * 0.08;
final barWidth = (size.width - gap * 4) / 5;
final strokePaint = Paint()
..color = FocusFlowTokens.textFaint
..style = PaintingStyle.stroke
..strokeWidth = 1.3;
final fillPaint = Paint()
..color = color
..style = PaintingStyle.fill;
for (var index = 0; index < 5; index += 1) {
final left = index * (barWidth + gap);
final height = size.height * (0.34 + index * 0.13);
final top = size.height - height;
final rect = RRect.fromRectAndRadius(
Rect.fromLTWH(left, top, barWidth, height),
Radius.circular(barWidth / 2),
);
if (index < filledCount) {
canvas.drawRRect(rect, fillPaint);
} else {
canvas.drawRRect(rect, strokePaint);
}
}
}
@override
bool shouldRepaint(covariant _DifficultyBarsPainter oldDelegate) {
return oldDelegate.filledCount != filledCount || oldDelegate.color != color;
}
}