Skip to content

Commit

Permalink
Update slider design
Browse files Browse the repository at this point in the history
  • Loading branch information
kra-mo committed Dec 18, 2024
1 parent f45cc58 commit c8c368a
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 10 deletions.
2 changes: 1 addition & 1 deletion lib/image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ class SlyImage {
Map<String, SlyRangeAttribute> effectAttributes = {
'denoise': SlyRangeAttribute('Noise Reduction', 0, 0, 0, 1),
'sharpness': SlyRangeAttribute('Sharpness', 0, 0, 0, 1),
'sepia': SlyRangeAttribute('Sepia', 0, 0, 0, 1),
'vignette': SlyRangeAttribute('Vignette', 0, 0, 0, 1),
'border': SlyRangeAttribute('Border', 0, 0, -1, 1),
'sepia': SlyRangeAttribute('Sepia', 0, 0, 0, 1),
};

/// For informational purposes only, not actually reflected in the buffer
Expand Down
24 changes: 24 additions & 0 deletions lib/widgets/controls_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ import '/image.dart';
import '/history.dart';
import '/widgets/slider_row.dart';

LinearGradient? getGradientForAttributeName(String name) {
switch (name) {
case 'temp':
return LinearGradient(colors: [
Colors.blue,
Colors.lightBlue.shade100,
Colors.yellow.shade200,
Colors.orange.shade400,
]);
case 'tint':
return LinearGradient(colors: [
Colors.lightGreen,
Colors.lightGreen.shade200,
Colors.purple.shade100,
Colors.purple.shade400,
]);
default:
return null;
}
}

class SlyControlsListView extends StatelessWidget {
final Map<String, SlyRangeAttribute> attributes;
final BoxConstraints constraints;
Expand Down Expand Up @@ -51,6 +72,9 @@ class SlyControlsListView extends StatelessWidget {
attributes.values.elementAt(index).value = value;
updateImage();
},
gradient: getGradientForAttributeName(
attributes.keys.elementAt(index),
),
),
);
},
Expand Down
108 changes: 99 additions & 9 deletions lib/widgets/slider.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math';

import 'package:flutter/material.dart';

class SlySlider extends StatefulWidget {
Expand All @@ -22,6 +24,7 @@ class SlySlider extends StatefulWidget {
this.focusNode,
this.autofocus = false,
this.allowedInteraction,
this.gradient,
});

final double value;
Expand All @@ -43,6 +46,7 @@ class SlySlider extends StatefulWidget {
final FocusNode? focusNode;
final bool autofocus;
final SliderInteraction? allowedInteraction;
final LinearGradient? gradient;

@override
State<SlySlider> createState() => _SlySliderState();
Expand All @@ -60,6 +64,7 @@ class _SlySliderState extends State<SlySlider> {
inactiveTrackColor: Theme.of(context).disabledColor,
trackHeight: 18,
thumbShape: InsetSliderThumbShape(),
trackShape: SlySliderTrackShape(widget.gradient),
overlayColor: Colors.transparent,
),
child: GestureDetector(
Expand Down Expand Up @@ -125,19 +130,104 @@ class InsetSliderThumbShape extends SliderComponentShape {
required double textScaleFactor,
required Size sizeWithOverflow,
}) {
context.canvas.drawCircle(
center,
10,
context.canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromCenter(
center: center,
width: 10 + (2 * activationAnimation.value),
height: 32 + (4 * activationAnimation.value),
),
const Radius.circular(6),
),
Paint()
..color = sliderTheme.activeTrackColor!
..style = PaintingStyle.fill,
);
context.canvas.drawCircle(
center,
6 * activationAnimation.value,
Paint()
..color = sliderTheme.inactiveTrackColor!
..style = PaintingStyle.fill,
}
}

class SlySliderTrackShape extends SliderTrackShape with BaseSliderTrackShape {
const SlySliderTrackShape(this.gradient);

final LinearGradient? gradient;

@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,
double additionalActiveTrackHeight = 2,
}) {
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 == null || sliderTheme.trackHeight! <= 0) {
return;
}

final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);

// Assign the track segment paints, which are leading: active and
// trailing: inactive.
final ColorTween activeTrackColorTween = ColorTween(
begin: sliderTheme.disabledActiveTrackColor,
end: sliderTheme.activeTrackColor);
final ColorTween inactiveTrackColorTween = ColorTween(
begin: sliderTheme.disabledInactiveTrackColor,
end: sliderTheme.inactiveTrackColor);
final Paint activePaint = Paint()
..color = activeTrackColorTween.evaluate(enableAnimation)!;
final Paint inactivePaint = Paint()
..shader = gradient?.createShader(trackRect)
..color = inactiveTrackColorTween.evaluate(enableAnimation)!;
final (Paint leftTrackPaint, Paint rightTrackPaint) =
switch (textDirection) {
TextDirection.ltr => (activePaint, inactivePaint),
TextDirection.rtl => (inactivePaint, activePaint),
};

const int thumbRadius = 5;
context.canvas.drawRRect(
RRect.fromLTRBR(
trackRect.left - thumbRadius,
trackRect.top,
trackRect.right + thumbRadius,
trackRect.bottom,
Radius.circular(trackRect.height / 2),
),
rightTrackPaint,
);

final bool isLTR = textDirection == TextDirection.ltr;
if (gradient == null && secondaryOffset != null) {
context.canvas.drawRRect(
RRect.fromLTRBR(
max(secondaryOffset.dx, thumbCenter.dx) + thumbRadius,
isLTR ? trackRect.top : trackRect.top,
min(secondaryOffset.dx, thumbCenter.dx) - thumbRadius,
isLTR ? trackRect.bottom : trackRect.bottom,
const Radius.circular(4),
),
leftTrackPaint,
);
}
}
}
3 changes: 3 additions & 0 deletions lib/widgets/slider_row.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class SlySliderRow extends StatefulWidget {
this.focusNode,
this.autofocus = false,
this.allowedInteraction,
this.gradient,
});

final double value;
Expand All @@ -45,6 +46,7 @@ class SlySliderRow extends StatefulWidget {
final FocusNode? focusNode;
final bool autofocus;
final SliderInteraction? allowedInteraction;
final LinearGradient? gradient;

@override
State<SlySliderRow> createState() => _SlySliderRowState();
Expand Down Expand Up @@ -91,6 +93,7 @@ class _SlySliderRowState extends State<SlySliderRow> {
focusNode: widget.focusNode,
autofocus: widget.autofocus,
allowedInteraction: widget.allowedInteraction,
gradient: widget.gradient,
);

@override
Expand Down

0 comments on commit c8c368a

Please sign in to comment.