aboutsummaryrefslogtreecommitdiffstats
path: root/lib/presentation/common_widget/volume_bar.dart
diff options
context:
space:
mode:
Diffstat (limited to 'lib/presentation/common_widget/volume_bar.dart')
-rw-r--r--lib/presentation/common_widget/volume_bar.dart356
1 files changed, 356 insertions, 0 deletions
diff --git a/lib/presentation/common_widget/volume_bar.dart b/lib/presentation/common_widget/volume_bar.dart
new file mode 100644
index 0000000..a029698
--- /dev/null
+++ b/lib/presentation/common_widget/volume_bar.dart
@@ -0,0 +1,356 @@
+import 'package:flutter_ics_homescreen/presentation/custom_icons/custom_icons.dart';
+
+import '../../export.dart';
+
+class VolumeBar extends ConsumerStatefulWidget {
+ const VolumeBar({super.key});
+
+ @override
+ VolumeBarState createState() => VolumeBarState();
+}
+
+class VolumeBarState extends ConsumerState<VolumeBar> {
+ double val = 0;
+ @override
+ void initState() {
+ super.initState();
+ // "ref" can be used in all life-cycles of a StatefulWidget.
+ //ref.read(counterProvider);
+ }
+
+ void increaseVolume() {
+ setState(() {
+ if (val < 20) {
+ val++;
+ ref.read(audioStateProvider.notifier).setVolume(val);
+ }
+ });
+ }
+
+ void decreaseVolume() {
+ setState(() {
+ if (val > 0) {
+ val--;
+ ref.read(audioStateProvider.notifier).setVolume(val);
+ }
+ });
+ }
+
+ void setVolume(double newWalue) {
+ setState(() {
+ val = newWalue;
+ ref.read(audioStateProvider.notifier).setVolume(val);
+ });
+ }
+
+ void pause() {}
+
+ @override
+ Widget build(BuildContext context) {
+ final volumeValue =
+ ref.watch(audioStateProvider.select((audio) => audio.volume));
+ val = volumeValue;
+ return Column(
+ // mainAxisAlignment: MainAxisAlignment.center,
+ // crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Container(
+ width: 80,
+ height: 418,
+ //padding: const EdgeInsets.all(16),
+ decoration: const ShapeDecoration(
+ // gradient: RadialGradient(
+ // colors: [Color.fromARGB(255, 19, 24, 75), Colors.black],
+ // stops: [0, 0.9],
+ // radius: 1,
+ // ),
+ color: AGLDemoColors.buttonFillEnabledColor,
+ shape: StadiumBorder(
+ side: BorderSide(
+ color: Color(0xFF5477D4),
+ width: 1,
+ )),
+ ),
+ //alignment: Alignment.topLeft,
+ child: Column(
+ children: [
+ SizedBox(
+ height: 68.0,
+ width: 56.0,
+ child: IconButton(
+ padding: EdgeInsets.zero,
+ color: AGLDemoColors.periwinkleColor,
+ onPressed: () {
+ increaseVolume();
+ },
+ icon: const Icon(
+ CustomIcons.vol_max,
+ size: 56,
+ ),
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(
+ top: 4, bottom: 4), // Top and bottom padding
+ child: SizedBox(
+ height: 274.0,
+ child: RotatedBox(
+ quarterTurns: 3,
+ child: SliderTheme(
+ data: SliderTheme.of(context).copyWith(
+ activeTrackColor: AGLDemoColors.periwinkleColor,
+ inactiveTrackColor: const Color(0xFF0D113F),
+ trackShape: const GradinetRectangularSliderTrackShape(),
+ //trackShape: CustomTrackShape(),
+ trackHeight: 56.0,
+ //thumbColor: Colors.blueAccent,
+ thumbShape: const RectSliderThumbShape(
+ enabledThumbRadius: 0, disabledThumbRadius: 0),
+ //overlayColor: Colors.red.withAlpha(32),
+ overlayShape:
+ //RoundSliderOverlayShape(overlayRadius: 33.0),
+ //RoundSliderOverlayShape(overlayRadius: 0.0),
+ SliderComponentShape.noOverlay,
+ ),
+ child: Slider(
+ min: 0,
+ max: 20,
+ value: volumeValue,
+ divisions: 20,
+ onChanged: (newValue) {
+ setVolume(newValue);
+ },
+ ),
+ ),
+ ),
+ ),
+ ),
+ SizedBox(
+ height: 56.0,
+ width: 56.0,
+ child: IconButton(
+ padding: EdgeInsets.zero,
+ color: AGLDemoColors.periwinkleColor,
+ onPressed: () {
+ decreaseVolume();
+ },
+ icon: const Icon(
+ CustomIcons.vol_min,
+ size: 56,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(height: 10),
+ Container(
+ width: 80,
+ height: 80,
+ //padding: const EdgeInsets.all(16),
+ decoration: const ShapeDecoration(
+ // gradient: RadialGradient(
+ // colors: [Color.fromARGB(255, 19, 24, 75), Colors.black],
+ // stops: [0, 0.9],
+ // radius: 1,
+ // ),
+ color: AGLDemoColors.buttonFillEnabledColor,
+ shape: StadiumBorder(
+ side: BorderSide(
+ color: Color(0xFF5477D4),
+ width: 1,
+ )),
+ ),
+ //alignment: Alignment.topLeft,
+ child: IconButton(
+ padding: EdgeInsets.zero,
+ color: AGLDemoColors.periwinkleColor,
+ onPressed: () {
+ pause();
+ },
+ icon: const Icon(
+ Icons.pause,
+ size: 30,
+ )),
+ ),
+ ],
+ );
+ }
+}
+
+class RectSliderThumbShape extends SliderComponentShape {
+ /// Create a slider thumb that draws a Rect.
+ const RectSliderThumbShape({
+ this.enabledThumbRadius = 10.0,
+ this.disabledThumbRadius,
+ this.elevation = 1.0,
+ this.pressedElevation = 6.0,
+ });
+
+ final double enabledThumbRadius;
+
+ final double? disabledThumbRadius;
+ double get _disabledThumbRadius => disabledThumbRadius ?? enabledThumbRadius;
+
+ final double elevation;
+
+ final double pressedElevation;
+
+ @override
+ Size getPreferredSize(bool isEnabled, bool isDiscrete) {
+ return Size.fromRadius(
+ isEnabled == true ? enabledThumbRadius : _disabledThumbRadius);
+ }
+
+ @override
+ void paint(
+ PaintingContext context,
+ Offset center, {
+ required Animation<double> activationAnimation,
+ required Animation<double> enableAnimation,
+ required bool isDiscrete,
+ required TextPainter labelPainter,
+ required RenderBox parentBox,
+ required SliderThemeData sliderTheme,
+ required TextDirection textDirection,
+ required double value,
+ required double textScaleFactor,
+ required Size sizeWithOverflow,
+ }) {
+ final Canvas canvas = context.canvas;
+
+ const Color color = Colors.white;
+ //const double radius = 0;
+
+ final Tween<double> elevationTween = Tween<double>(
+ begin: elevation,
+ end: pressedElevation,
+ );
+
+ final double evaluatedElevation =
+ elevationTween.evaluate(activationAnimation);
+
+ final Path path = Path()
+ ..addRect(
+ Rect.fromCenter(
+ center: Offset(center.dx - 3, center.dy + 2), width: 3, height: 54),
+ );
+
+ // canvas.drawRect(
+ // Rect.fromCenter(center: center, width: 4, height: 25),
+ // Paint()..color = color,
+ // );
+ canvas.drawRect(
+ Rect.fromCenter(center: center, width: 4, height: 54),
+ Paint()..color = color,
+ );
+ canvas.drawShadow(path, Colors.black, evaluatedElevation, true);
+ }
+}
+
+class GradinetRectangularSliderTrackShape extends SliderTrackShape
+ with BaseSliderTrackShape {
+ /// Creates a slider track that draws 2 rectangles.
+ const GradinetRectangularSliderTrackShape();
+
+ @override
+ void paint(
+ PaintingContext context,
+ Offset offset, {
+ required RenderBox parentBox,
+ required SliderThemeData sliderTheme,
+ required Animation<double> enableAnimation,
+ required TextDirection textDirection,
+ required Offset thumbCenter,
+ Offset? secondaryOffset,
+ bool isDiscrete = false,
+ bool isEnabled = false,
+ }) {
+ assert(sliderTheme.disabledActiveTrackColor != null);
+ assert(sliderTheme.disabledInactiveTrackColor != null);
+ assert(sliderTheme.activeTrackColor != null);
+ assert(sliderTheme.inactiveTrackColor != null);
+ assert(sliderTheme.thumbShape != null);
+ // If the slider [SliderThemeData.trackHeight] is less than or equal to 0,
+ // then it makes no difference whether the track is painted or not,
+ // therefore the painting can be a no-op.
+ if (sliderTheme.trackHeight! <= 0) {
+ return;
+ }
+
+ LinearGradient gradient = const LinearGradient(
+ colors: <Color>[
+ //AGLDemoColors.periwinkleColor,
+ Color(0xff81A9ED),
+ Colors.white,
+ ],
+ );
+ final Rect trackRect = getPreferredRect(
+ parentBox: parentBox,
+ offset: offset,
+ sliderTheme: sliderTheme,
+ isEnabled: isEnabled,
+ isDiscrete: isDiscrete,
+ );
+ // Assign the track segment paints, which are left: active, right: inactive,
+ // but reversed for right to left text.
+ final ColorTween activeTrackColorTween = ColorTween(
+ begin: sliderTheme.disabledActiveTrackColor,
+ end: sliderTheme.activeTrackColor);
+ final ColorTween inactiveTrackColorTween = ColorTween(
+ begin: sliderTheme.disabledInactiveTrackColor,
+ end: sliderTheme.inactiveTrackColor);
+ final Paint activePaint = Paint()
+ ..shader = gradient.createShader(trackRect)
+ ..color = activeTrackColorTween.evaluate(enableAnimation)!;
+ final Paint inactivePaint = Paint()
+ ..color = inactiveTrackColorTween.evaluate(enableAnimation)!;
+ final Paint leftTrackPaint;
+ final Paint rightTrackPaint;
+ switch (textDirection) {
+ case TextDirection.ltr:
+ leftTrackPaint = activePaint;
+ rightTrackPaint = inactivePaint;
+ case TextDirection.rtl:
+ leftTrackPaint = inactivePaint;
+ rightTrackPaint = activePaint;
+ }
+
+ final Rect leftTrackSegment = Rect.fromLTRB(
+ trackRect.left, trackRect.top, thumbCenter.dx, trackRect.bottom);
+ if (!leftTrackSegment.isEmpty) {
+ context.canvas.drawRect(leftTrackSegment, leftTrackPaint);
+ }
+ final Rect rightTrackSegment = Rect.fromLTRB(
+ thumbCenter.dx, trackRect.top, trackRect.right, trackRect.bottom);
+ if (!rightTrackSegment.isEmpty) {
+ context.canvas.drawRect(rightTrackSegment, rightTrackPaint);
+ }
+
+ final bool showSecondaryTrack = (secondaryOffset != null) &&
+ ((textDirection == TextDirection.ltr)
+ ? (secondaryOffset.dx > thumbCenter.dx)
+ : (secondaryOffset.dx < thumbCenter.dx));
+
+ if (showSecondaryTrack) {
+ final ColorTween secondaryTrackColorTween = ColorTween(
+ begin: sliderTheme.disabledSecondaryActiveTrackColor,
+ end: sliderTheme.secondaryActiveTrackColor);
+ final Paint secondaryTrackPaint = Paint()
+ ..color = secondaryTrackColorTween.evaluate(enableAnimation)!;
+ final Rect secondaryTrackSegment = Rect.fromLTRB(
+ (textDirection == TextDirection.ltr)
+ ? thumbCenter.dx
+ : secondaryOffset.dx,
+ trackRect.top,
+ (textDirection == TextDirection.ltr)
+ ? secondaryOffset.dx
+ : thumbCenter.dx,
+ trackRect.bottom,
+ );
+ if (!secondaryTrackSegment.isEmpty) {
+ context.canvas.drawRect(secondaryTrackSegment, secondaryTrackPaint);
+ }
+ }
+ }
+}