mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-19 09:52:03 +00:00
200 lines
5.5 KiB
Dart
200 lines
5.5 KiB
Dart
import 'dart:math';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
class CustomTrackShape extends SliderTrackShape {
|
|
final double maxValue;
|
|
final double minValue;
|
|
final double currentPosition;
|
|
final double bufferPosition;
|
|
final List<(String, int)> chapterMarks;
|
|
final double chapterMarkWidth;
|
|
double trackWidth;
|
|
|
|
CustomTrackShape({
|
|
required this.maxValue,
|
|
required this.minValue,
|
|
required this.currentPosition,
|
|
required this.bufferPosition,
|
|
required this.chapterMarks,
|
|
this.chapterMarkWidth = 3,
|
|
this.trackWidth = 5,
|
|
});
|
|
|
|
@override
|
|
Rect getPreferredRect({
|
|
required RenderBox parentBox,
|
|
Offset offset = Offset.zero,
|
|
required SliderThemeData sliderTheme,
|
|
bool? isEnabled,
|
|
bool? isDiscrete,
|
|
}) {
|
|
final double thumbWidth = sliderTheme.thumbShape!
|
|
.getPreferredSize(isEnabled ?? true, isDiscrete ?? false)
|
|
.width;
|
|
final double trackHeight = sliderTheme.trackHeight!;
|
|
|
|
final double trackTop =
|
|
offset.dy + (parentBox.size.height - trackHeight) / 2;
|
|
final double trackLeft = offset.dx + thumbWidth / 2;
|
|
trackWidth = parentBox.size.width - thumbWidth;
|
|
|
|
return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
|
|
}
|
|
|
|
@override
|
|
void paint(
|
|
PaintingContext context,
|
|
Offset offset, {
|
|
required RenderBox parentBox,
|
|
required SliderThemeData sliderTheme,
|
|
required Animation<double> enableAnimation,
|
|
required Offset thumbCenter,
|
|
Offset? secondaryOffset,
|
|
bool? isEnabled,
|
|
bool? isDiscrete,
|
|
required TextDirection textDirection,
|
|
}) {
|
|
if (sliderTheme.trackHeight == 0) return;
|
|
final Rect trackRect = getPreferredRect(
|
|
parentBox: parentBox,
|
|
offset: offset,
|
|
sliderTheme: sliderTheme,
|
|
isEnabled: isEnabled,
|
|
isDiscrete: isDiscrete,
|
|
);
|
|
double currentPositionWidth = (trackWidth / maxValue) * currentPosition;
|
|
double bufferPositionWidth = (trackWidth / maxValue) * bufferPosition;
|
|
|
|
_drawActiveThumb(context, sliderTheme, trackRect, currentPositionWidth);
|
|
_drawBufferThumb(
|
|
context,
|
|
sliderTheme,
|
|
trackRect,
|
|
currentPositionWidth,
|
|
bufferPositionWidth,
|
|
);
|
|
_drawInactiveThumb(context, sliderTheme, trackRect, currentPositionWidth);
|
|
|
|
for (final mark in chapterMarks) {
|
|
double markPositionWidth = (trackWidth / maxValue) * mark.$2;
|
|
_drawChapterMark(context, sliderTheme, trackRect, markPositionWidth);
|
|
}
|
|
}
|
|
|
|
void _drawActiveThumb(
|
|
PaintingContext context,
|
|
SliderThemeData sliderTheme,
|
|
Rect trackRect,
|
|
double currentPositionWidth,
|
|
) {
|
|
final Paint defaultPathPaint = Paint()
|
|
..color = sliderTheme.activeTrackColor!
|
|
..style = PaintingStyle.fill;
|
|
|
|
final defaultPathSegment = Path()
|
|
..addRect(
|
|
Rect.fromPoints(
|
|
Offset(trackRect.left, trackRect.top),
|
|
Offset(trackRect.left + currentPositionWidth, trackRect.bottom),
|
|
),
|
|
)
|
|
..lineTo(trackRect.left, trackRect.bottom)
|
|
..arcTo(
|
|
Rect.fromPoints(
|
|
Offset(trackRect.left + 5, trackRect.top),
|
|
Offset(trackRect.left - 5, trackRect.bottom),
|
|
),
|
|
-pi * 3 / 2,
|
|
pi,
|
|
false,
|
|
);
|
|
|
|
context.canvas.drawPath(defaultPathSegment, defaultPathPaint);
|
|
}
|
|
|
|
void _drawBufferThumb(
|
|
PaintingContext context,
|
|
SliderThemeData sliderTheme,
|
|
Rect trackRect,
|
|
double currentPositionWidth,
|
|
double bufferPositionWidth,
|
|
) {
|
|
final Paint defaultPathPaint = Paint()
|
|
..color = sliderTheme.secondaryActiveTrackColor!
|
|
..style = PaintingStyle.fill;
|
|
|
|
final defaultPathSegment = Path()
|
|
..addRect(
|
|
Rect.fromPoints(
|
|
Offset(trackRect.left + currentPositionWidth, trackRect.top),
|
|
Offset(trackRect.left + bufferPositionWidth, trackRect.bottom),
|
|
),
|
|
)
|
|
..lineTo(trackRect.left, trackRect.bottom)
|
|
..arcTo(
|
|
Rect.fromPoints(
|
|
Offset(trackRect.left + 5, trackRect.top),
|
|
Offset(trackRect.left - 5, trackRect.bottom),
|
|
),
|
|
-pi * 3 / 2,
|
|
pi,
|
|
false,
|
|
);
|
|
|
|
context.canvas.drawPath(defaultPathSegment, defaultPathPaint);
|
|
}
|
|
|
|
void _drawInactiveThumb(
|
|
PaintingContext context,
|
|
SliderThemeData sliderTheme,
|
|
Rect trackRect,
|
|
double currentPositionWidth,
|
|
) {
|
|
final unselectedPathPaint = Paint()
|
|
..style = PaintingStyle.fill
|
|
..color = sliderTheme.inactiveTrackColor!;
|
|
|
|
final unselectedPathSegment = Path()
|
|
..addRect(
|
|
Rect.fromPoints(
|
|
Offset(trackRect.right, trackRect.top),
|
|
Offset(trackRect.left + currentPositionWidth, trackRect.bottom),
|
|
),
|
|
)
|
|
..addArc(
|
|
Rect.fromPoints(
|
|
Offset(trackRect.right - 5, trackRect.bottom),
|
|
Offset(trackRect.right + 5, trackRect.top),
|
|
),
|
|
-pi / 2,
|
|
pi,
|
|
);
|
|
|
|
context.canvas.drawPath(unselectedPathSegment, unselectedPathPaint);
|
|
}
|
|
|
|
void _drawChapterMark(
|
|
PaintingContext context,
|
|
SliderThemeData sliderTheme,
|
|
Rect trackRect,
|
|
double markPositionWidth,
|
|
) {
|
|
final Paint borderPaint = Paint()
|
|
..color = Colors.white
|
|
..style = PaintingStyle.fill;
|
|
|
|
final pathSegmentSelected = Path()
|
|
..addRect(
|
|
Rect.fromPoints(
|
|
Offset(trackRect.left + markPositionWidth, trackRect.top),
|
|
Offset(
|
|
trackRect.left + markPositionWidth + chapterMarkWidth,
|
|
trackRect.bottom,
|
|
),
|
|
),
|
|
);
|
|
|
|
context.canvas.drawPath(pathSegmentSelected, borderPaint);
|
|
}
|
|
}
|