m3_lightmeter/lib/screens/shared/ruler_slider/widget_slider_ruler.dart
Vadim 2117df2f11
ML-44 Save zoom level for equipment profile (#164)
* made zoom slider vertical & added more ticks to ruler

* show sliders values

* increased slider tappable area

* more accurate sliders values

* added zoom slider to equipment profiles settings

* split `EquipmentListTiles` widget

* set zoom on equipment profile change

* clamp zoom to the nearest value

* added missing translations

* added zoom checks to e2e test

* removed unused import
2024-04-07 10:54:57 +02:00

121 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/res/dimens.dart';
import 'package:lightmeter/screens/shared/centered_slider/widget_slider_centered.dart';
class RulerSlider extends StatelessWidget {
final IconData icon;
final RangeValues range;
final double value;
final double defaultValue;
final ValueChanged<double> onChanged;
final String Function(double value) rulerValueAdapter;
final String Function(double value) valueAdapter;
const RulerSlider({
required this.icon,
required this.range,
required this.value,
required this.defaultValue,
required this.onChanged,
required this.rulerValueAdapter,
required this.valueAdapter,
super.key,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
valueAdapter(value),
style: Theme.of(context).textTheme.labelLarge,
),
const SizedBox(height: Dimens.grid4),
Expanded(
child: Row(
children: [
_Ruler(
range.start,
range.end,
rulerValueAdapter,
),
CenteredSlider(
isVertical: true,
icon: Icon(icon),
value: value,
min: range.start,
max: range.end,
onChanged: onChanged,
),
],
),
),
IconButton(
icon: const Icon(Icons.sync),
onPressed: value != defaultValue ? () => onChanged(defaultValue) : null,
tooltip: S.of(context).tooltipResetToZero,
),
],
);
}
}
class _Ruler extends StatelessWidget {
final double min;
final double max;
final String Function(double value) rulerValueAdapter;
late final int mainTicksCount = (max - min + 1).toInt();
late final int itemsCount = mainTicksCount * 2 - 1;
_Ruler(
this.min,
this.max,
this.rulerValueAdapter,
);
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final bool showAllMainTicks = Dimens.cameraSliderHandleArea * mainTicksCount <= constraints.maxHeight;
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(
itemsCount,
(index) {
final bool isMainTick = index % 2 == 0.0;
if (!showAllMainTicks && !isMainTick) {
return const SizedBox();
}
final bool showValue = (index % (showAllMainTicks ? 2 : 4) == 0.0);
return SizedBox(
height: index == itemsCount - 1 || showValue ? Dimens.cameraSliderHandleArea : 1,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (showValue)
Text(
rulerValueAdapter(index / 2 + min),
style: Theme.of(context).textTheme.bodySmall,
),
const SizedBox(width: Dimens.grid4),
ColoredBox(
color: Theme.of(context).colorScheme.onBackground,
child: SizedBox(
height: 1,
width: isMainTick ? Dimens.grid8 : Dimens.grid4,
),
),
],
),
);
},
).reversed.toList(),
);
},
);
}
}