Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ColorPickerHueRing improvements #87

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 69 additions & 11 deletions lib/src/palette.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1332,13 +1332,21 @@ class ColorPickerHueRing extends StatelessWidget {
Key? key,
this.displayThumbColor = true,
this.strokeWidth = 5.0,
this.gesturesOnlyInside = false,
this.onEnd,
}) : super(key: key);

final HSVColor hsvColor;
final ValueChanged<HSVColor> onColorChanged;
final bool displayThumbColor;
final double strokeWidth;

/// Whether to recognize gestures only when inside the hue ring or anywhere in it’s bounds
final bool gesturesOnlyInside;

/// Callback called when the user finishes interacting with color picker
final VoidCallback? onEnd;

void _handleGesture(Offset position, BuildContext context, double height, double width) {
RenderBox? getBox = context.findRenderObject() as RenderBox?;
if (getBox == null) return;
Expand All @@ -1361,19 +1369,37 @@ class ColorPickerHueRing extends StatelessWidget {
double width = constraints.maxWidth;
double height = constraints.maxHeight;

final gestureInitializer = (PanGestureRecognizer instance) {
instance
..onDown = ((details) => _handleGesture(details.globalPosition, context, height, width))
..onUpdate =
((details) => _handleGesture(details.globalPosition, context, height, width))
..onEnd = (_) => onEnd?.call();
};

return RawGestureDetector(
gestures: {
_AlwaysWinPanGestureRecognizer: GestureRecognizerFactoryWithHandlers<_AlwaysWinPanGestureRecognizer>(
() => _AlwaysWinPanGestureRecognizer(),
(_AlwaysWinPanGestureRecognizer instance) {
instance
..onDown = ((details) => _handleGesture(details.globalPosition, context, height, width))
..onUpdate = ((details) => _handleGesture(details.globalPosition, context, height, width));
},
),
},
gestures: !gesturesOnlyInside
? {
_AlwaysWinPanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<_AlwaysWinPanGestureRecognizer>(
() => _AlwaysWinPanGestureRecognizer(),
gestureInitializer,
),
}
: {
_InsideRingPanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<_InsideRingPanGestureRecognizer>(
() => _InsideRingPanGestureRecognizer(
width: width,
height: height,
strokeWidth: strokeWidth,
),
gestureInitializer,
),
},
child: CustomPaint(
painter: HueRingPainter(hsvColor, displayThumbColor: displayThumbColor, strokeWidth: strokeWidth),
painter: HueRingPainter(hsvColor,
displayThumbColor: displayThumbColor, strokeWidth: strokeWidth),
),
);
},
Expand All @@ -1392,6 +1418,38 @@ class _AlwaysWinPanGestureRecognizer extends PanGestureRecognizer {
String get debugDescription => 'alwaysWin';
}

/// Pan gesture recgonizer that only accepts pointers inside the hue ring
class _InsideRingPanGestureRecognizer extends PanGestureRecognizer {
final Offset center;
final double radio;
final double strokeWidth;

_InsideRingPanGestureRecognizer({
required width,
required height,
required this.strokeWidth,
}) : center = Offset(width / 2, height / 2),
radio = width <= height ? width / 2 : height / 2,
super();

@override
void addAllowedPointer(event) {
final x = pow(event.localPosition.dx - center.dx, 2);
final y = pow(event.localPosition.dy - center.dy, 2);
final bool passTest = x + y <= pow(radio, 2) && x + y >= pow(radio - strokeWidth, 2);

if (passTest) {
super.addAllowedPointer(event);
resolve(GestureDisposition.accepted);
} else {
resolve(GestureDisposition.rejected);
}
}

@override
String get debugDescription => 'insideRing';
}

/// Uppercase text formater
class UpperCaseTextFormatter extends TextInputFormatter {
@override
Expand Down