buildExposureSlider method

Widget buildExposureSlider({
  1. required ExposureMode mode,
  2. required double size,
  3. required double height,
  4. required double gap,
})

Implementation

Widget buildExposureSlider({
  required ExposureMode mode,
  required double size,
  required double height,
  required double gap,
}) {
  final bool isLocked = mode == ExposureMode.locked;
  final Color? color = isLocked ? _lockedColor : theme.iconTheme.color;
  final Widget lineWidget = ValueListenableBuilder<bool>(
    valueListenable: isFocusPointDisplays,
    builder: (_, bool value, Widget? child) => AnimatedOpacity(
      duration: _kDuration,
      opacity: value ? 1 : 0,
      child: child,
    ),
    child: Center(child: Container(width: 1, color: color)),
  );

  return ValueListenableBuilder<double>(
    valueListenable: currentExposureOffset,
    builder: (_, double exposure, __) {
      final double effectiveTop = (size + gap) +
          (minAvailableExposureOffset.abs() - exposure) *
              (height - size * 3) /
              (maxAvailableExposureOffset - minAvailableExposureOffset);
      final double effectiveBottom = height - effectiveTop - size;
      return Stack(
        clipBehavior: Clip.none,
        children: <Widget>[
          Positioned.fill(top: effectiveTop + gap, child: lineWidget),
          Positioned.fill(bottom: effectiveBottom + gap, child: lineWidget),
          Positioned(
            top: (minAvailableExposureOffset.abs() - exposure) *
                (height - size * 3) /
                (maxAvailableExposureOffset - minAvailableExposureOffset),
            child: Transform.rotate(
              angle: exposure,
              child: Icon(Icons.wb_sunny_outlined, size: size, color: color),
            ),
          ),
          Positioned.fill(
            top: -10,
            bottom: -10,
            child: RotatedBox(
              quarterTurns: 3,
              child: Directionality(
                textDirection: TextDirection.ltr,
                child: Opacity(
                  opacity: 0,
                  child: Slider(
                    value: exposure,
                    min: minAvailableExposureOffset,
                    max: maxAvailableExposureOffset,
                    onChanged: updateExposureOffset,
                  ),
                ),
              ),
            ),
          ),
        ],
      );
    },
  );
}