Skip to content

Commit

Permalink
feat: togglable canvas scale (#777)
Browse files Browse the repository at this point in the history
* feat: simplify togglable code

Use canvas scale to simplify tooglable code.

* Update goldens
  • Loading branch information
Jupi007 committed Sep 19, 2023
1 parent 09490fb commit 51bf33d
Show file tree
Hide file tree
Showing 46 changed files with 49 additions and 69 deletions.
45 changes: 21 additions & 24 deletions lib/src/widgets/yaru_checkbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -268,51 +268,48 @@ class _YaruCheckboxPainter extends YaruTogglablePainter {
@override
void paintTogglable(
Canvas canvas,
Size realSize,
Size size,
Offset origin,
double t,
) {
drawStateIndicator(canvas, realSize, null);
drawStateIndicator(canvas, size);
_drawBox(
canvas,
size,
origin,
oldChecked == false || checked == false ? t : 1,
);

// Four cases: false to null, false to true, null to false, true to false
if (oldChecked == false || checked == false) {
if (oldChecked == true || checked == true) {
_drawCheckMark(canvas, size, origin, t);
_drawCheckMark(canvas, size, t);
} else if (oldChecked == null || checked == null) {
_drawDash(canvas, size, origin, t);
_drawDash(canvas, size, t);
}
}
// Two cases: null to true, true to null
else {
if (t <= 0.5) {
final tShrink = 1 - t * 2;
if (oldChecked == true) {
_drawCheckMark(canvas, size, origin, tShrink);
_drawCheckMark(canvas, size, tShrink);
} else {
_drawDash(canvas, size, origin, tShrink);
_drawDash(canvas, size, tShrink);
}
} else {
final tExpand = (t - 0.5) * 2.0;
if (checked == true) {
_drawCheckMark(canvas, size, origin, tExpand);
_drawCheckMark(canvas, size, tExpand);
} else {
_drawDash(canvas, size, origin, tExpand);
_drawDash(canvas, size, tExpand);
}
}
}
}

void _drawBox(Canvas canvas, Size size, Offset origin, double t) {
void _drawBox(Canvas canvas, Size size, double t) {
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(origin.dx, origin.dy, size.width, size.height),
Offset.zero & size,
_kCheckboxBorderRadius,
),
Paint()
Expand All @@ -325,8 +322,8 @@ class _YaruCheckboxPainter extends YaruTogglablePainter {
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(
origin.dx + 0.5,
origin.dy + 0.5,
0.5,
0.5,
size.width - 1.0,
size.height - 1.0,
),
Expand All @@ -344,7 +341,7 @@ class _YaruCheckboxPainter extends YaruTogglablePainter {
);
}

void _drawCheckMark(Canvas canvas, Size size, Offset origin, double t) {
void _drawCheckMark(Canvas canvas, Size size, double t) {
final path = Path();

final start = Offset(size.width * 0.1818, size.height * 0.4545);
Expand All @@ -355,16 +352,16 @@ class _YaruCheckboxPainter extends YaruTogglablePainter {
final strokeT = t * 2.0;
final drawMid = Offset.lerp(start, mid, strokeT)!;

path.moveTo(origin.dx + start.dx, origin.dy + start.dy);
path.lineTo(origin.dx + drawMid.dx, origin.dy + drawMid.dy);
path.lineTo(origin.dx + start.dx, origin.dy + start.dy);
path.moveTo(start.dx, start.dy);
path.lineTo(drawMid.dx, drawMid.dy);
path.lineTo(start.dx, start.dy);
} else {
final strokeT = (t - 0.5) * 2.0;
final drawEnd = Offset.lerp(mid, end, strokeT)!;

path.moveTo(origin.dx + start.dx, origin.dy + start.dy);
path.lineTo(origin.dx + mid.dx, origin.dy + mid.dy);
path.lineTo(origin.dx + drawEnd.dx, origin.dy + drawEnd.dy);
path.moveTo(start.dx, start.dy);
path.lineTo(mid.dx, mid.dy);
path.lineTo(drawEnd.dx, drawEnd.dy);
}

canvas.drawPath(
Expand All @@ -373,7 +370,7 @@ class _YaruCheckboxPainter extends YaruTogglablePainter {
);
}

void _drawDash(Canvas canvas, Size size, Offset origin, double t) {
void _drawDash(Canvas canvas, Size size, double t) {
const dashMarginFactor = (1 - _kDashSizeFactor) / 2;

final start = Offset(size.width * dashMarginFactor, size.height * 0.5);
Expand All @@ -384,8 +381,8 @@ class _YaruCheckboxPainter extends YaruTogglablePainter {
final drawEnd = Offset.lerp(mid, end, t)!;

canvas.drawLine(
origin + drawStart,
origin + drawEnd,
drawStart,
drawEnd,
_getCheckmarkPaint(),
);
}
Expand Down
28 changes: 8 additions & 20 deletions lib/src/widgets/yaru_radio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -260,24 +260,17 @@ class _YaruRadioPainter extends YaruTogglablePainter {
@override
void paintTogglable(
Canvas canvas,
Size realSize,
Size size,
Offset origin,
double t,
) {
drawStateIndicator(canvas, realSize, null);
_drawBox(canvas, size, origin, t);
_drawDot(canvas, size, origin, t);
drawStateIndicator(canvas, size);
_drawBox(canvas, size, t);
_drawDot(canvas, size, t);
}

void _drawBox(Canvas canvas, Size size, Offset origin, double t) {
void _drawBox(Canvas canvas, Size size, double t) {
canvas.drawOval(
Rect.fromLTWH(
origin.dx,
origin.dy,
size.width,
size.height,
),
Offset.zero & size,
Paint()
..color = interactive
? Color.lerp(uncheckedColor, checkedColor, t)!
Expand All @@ -286,12 +279,7 @@ class _YaruRadioPainter extends YaruTogglablePainter {
);

canvas.drawOval(
Rect.fromLTWH(
origin.dx + 0.5,
origin.dy + 0.5,
size.width - 1.0,
size.height - 1.0,
),
Rect.fromLTWH(0.5, 0.5, size.width - 1.0, size.height - 1.0),
Paint()
..color = interactive
? Color.lerp(uncheckedBorderColor, checkedBorderColor, t)!
Expand All @@ -304,8 +292,8 @@ class _YaruRadioPainter extends YaruTogglablePainter {
);
}

void _drawDot(Canvas canvas, Size size, Offset origin, double t) {
final center = (Offset.zero & size).center + origin;
void _drawDot(Canvas canvas, Size size, double t) {
final center = (Offset.zero & size).center;
final dotSize = size * _kDotSizeFactor;

canvas.drawOval(
Expand Down
18 changes: 8 additions & 10 deletions lib/src/widgets/yaru_switch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -312,19 +312,17 @@ class _YaruSwitchPainter extends YaruTogglablePainter {
@override
void paintTogglable(
Canvas canvas,
Size realSize,
Size size,
Offset origin,
double t,
) {
_drawBox(canvas, size, origin, t);
_drawThumb(canvas, size, origin, t);
_drawBox(canvas, size, t);
_drawThumb(canvas, size, t);
}

void _drawBox(Canvas canvas, Size size, Offset origin, double t) {
void _drawBox(Canvas canvas, Size size, double t) {
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(origin.dx, origin.dy, size.width, size.height),
Offset.zero & size,
Radius.circular(size.height),
),
Paint()
Expand All @@ -337,8 +335,8 @@ class _YaruSwitchPainter extends YaruTogglablePainter {
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(
origin.dx + 0.5,
origin.dy + 0.5,
0.5,
0.5,
size.width - 1.0,
size.height - 1.0,
),
Expand All @@ -356,7 +354,7 @@ class _YaruSwitchPainter extends YaruTogglablePainter {
);
}

void _drawThumb(Canvas canvas, Size size, Offset origin, double t) {
void _drawThumb(Canvas canvas, Size size, double t) {
final margin = (size.height - size.height * _kSwitchThumbSizeFactor) / 2;
final innerSize = Size(
size.width - margin * 2,
Expand All @@ -366,7 +364,7 @@ class _YaruSwitchPainter extends YaruTogglablePainter {

final start = Offset(radius + margin, radius + margin);
final end = Offset(innerSize.width + margin - radius, radius + margin);
final center = Offset.lerp(start, end, t)! + origin;
final center = Offset.lerp(start, end, t)!;

final paint = Paint()
..color = interactive
Expand Down
27 changes: 12 additions & 15 deletions lib/src/widgets/yaru_togglable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const _kTogglableSizeAnimationDuration = Duration(milliseconds: 100);
const _kIndicatorAnimationDuration = Duration(milliseconds: 200);
const _kIndicatorRadius = 20.0;
// Used to resize the canvas on active state. Must be an even number.
const _kTogglableActiveResizeFactor = 2;
const _kTogglableActiveResizeFactor = .1;

/// A generic class to create a togglable widget
///
Expand Down Expand Up @@ -411,7 +411,7 @@ abstract class YaruTogglablePainter extends ChangeNotifier
notifyListeners();
}

void drawStateIndicator(Canvas canvas, Size canvasSize, Offset? offset) {
void drawStateIndicator(Canvas canvas, Size canvasSize, [Offset? offset]) {
if (interactive) {
final defaultOffset = Offset(canvasSize.width / 2, canvasSize.height / 2);
final color = focused ? focusIndicatorColor : hoverIndicatorColor;
Expand All @@ -426,25 +426,22 @@ abstract class YaruTogglablePainter extends ChangeNotifier

@override
void paint(Canvas canvas, Size size) {
final canvasSize = size;
final t = position.value;
final drawingOrigin = Offset(
_kTogglableActiveResizeFactor / 2 * sizePosition.value,
_kTogglableActiveResizeFactor / 2 * sizePosition.value,
);
final drawingSize = Size(
canvasSize.width - _kTogglableActiveResizeFactor * sizePosition.value,
canvasSize.height - _kTogglableActiveResizeFactor * sizePosition.value,
);
final origin = (Offset.zero & size).center;
final scale = 1 - _kTogglableActiveResizeFactor * sizePosition.value;

canvas.save();
canvas.translate(origin.dx, origin.dy);
canvas.scale(scale);
canvas.translate(-origin.dx, -origin.dy);

paintTogglable(canvas, size, position.value);

paintTogglable(canvas, size, drawingSize, drawingOrigin, t);
canvas.restore();
}

void paintTogglable(
Canvas canvas,
Size realSize,
Size size,
Offset origin,
double t,
);

Expand Down
Binary file modified test/widgets/goldens/yaru_check_button-checked-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_check_button-checked-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_check_button-tristate-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_check_button-unckecked-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_checkbox-checked-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_checkbox-checked-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_checkbox-tristate-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_checkbox-tristate-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_checkbox-unckecked-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_checkbox-unckecked-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_radio-checked-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_radio-checked-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_radio-unckecked-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_radio-unckecked-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_radio_button-checked-pressed-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_radio_button-checked-pressed-light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/widgets/goldens/yaru_radio_list_tile-checked-pressed-dark.png
Binary file modified test/widgets/goldens/yaru_switch-checked-pressed-dark.png
Binary file modified test/widgets/goldens/yaru_switch-checked-pressed-light.png
Binary file modified test/widgets/goldens/yaru_switch-unckecked-pressed-dark.png
Binary file modified test/widgets/goldens/yaru_switch-unckecked-pressed-light.png
Binary file modified test/widgets/goldens/yaru_switch_button-off-pressed-dark.png
Binary file modified test/widgets/goldens/yaru_switch_button-off-pressed-light.png
Binary file modified test/widgets/goldens/yaru_switch_button-on-pressed-dark.png
Binary file modified test/widgets/goldens/yaru_switch_button-on-pressed-light.png
Binary file modified test/widgets/goldens/yaru_switch_list_tile-off-pressed-dark.png
Binary file modified test/widgets/goldens/yaru_switch_list_tile-off-pressed-light.png
Binary file modified test/widgets/goldens/yaru_switch_list_tile-on-pressed-dark.png
Binary file modified test/widgets/goldens/yaru_switch_list_tile-on-pressed-light.png

0 comments on commit 51bf33d

Please sign in to comment.