Skip to content

Commit

Permalink
YaruCheck/Radio/SwitchButton: add hover & press effects (#663)
Browse files Browse the repository at this point in the history
Add hover & press effect for the indicator when hovering the label to highlight
the interactive nature of the label.

This becomes more important if the web-orientend pointing finger mouse
cursor is changed to a more desktop'ish "basic" mouse cursor.

Close: #659
  • Loading branch information
jpnurmi committed Mar 6, 2023
1 parent d9ac8a4 commit 1dd727a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 12 deletions.
26 changes: 23 additions & 3 deletions lib/src/widgets/yaru_check_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,29 @@ class YaruCheckButton extends StatefulWidget {
}

class _YaruCheckButtonState extends State<YaruCheckButton> {
final _statesController = MaterialStatesController();

@override
void initState() {
super.initState();
_statesController.update(MaterialState.disabled, widget.onChanged == null);
}

@override
void didUpdateWidget(YaruCheckButton oldWidget) {
super.didUpdateWidget(oldWidget);
_statesController.update(MaterialState.disabled, widget.onChanged == null);
}

@override
void dispose() {
_statesController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
final states = {
if (widget.onChanged == null) MaterialState.disabled,
};
final states = _statesController.value;
final mouseCursor =
MaterialStateProperty.resolveAs(widget.mouseCursor, states) ??
YaruToggleButtonTheme.of(context)?.mouseCursor?.resolve(states);
Expand All @@ -72,9 +90,11 @@ class _YaruCheckButtonState extends State<YaruCheckButton> {
focusNode: widget.focusNode,
autofocus: widget.autofocus,
mouseCursor: mouseCursor,
statesController: _statesController,
),
mouseCursor:
mouseCursor ?? MaterialStateMouseCursor.clickable.resolve(states),
statesController: _statesController,
onToggled: widget.onChanged == null ? null : _onToggled,
);
}
Expand Down
26 changes: 23 additions & 3 deletions lib/src/widgets/yaru_radio_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,29 @@ class YaruRadioButton<T> extends StatefulWidget {
}

class _YaruRadioButtonState<T> extends State<YaruRadioButton<T>> {
final _statesController = MaterialStatesController();

@override
void initState() {
super.initState();
_statesController.update(MaterialState.disabled, widget.onChanged == null);
}

@override
void didUpdateWidget(YaruRadioButton<T> oldWidget) {
super.didUpdateWidget(oldWidget);
_statesController.update(MaterialState.disabled, widget.onChanged == null);
}

@override
void dispose() {
_statesController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
final states = {
if (widget.onChanged == null) MaterialState.disabled,
};
final states = _statesController.value;
final mouseCursor =
MaterialStateProperty.resolveAs(widget.mouseCursor, states) ??
YaruToggleButtonTheme.of(context)?.mouseCursor?.resolve(states);
Expand All @@ -77,9 +95,11 @@ class _YaruRadioButtonState<T> extends State<YaruRadioButton<T>> {
focusNode: widget.focusNode,
autofocus: widget.autofocus,
mouseCursor: mouseCursor,
statesController: _statesController,
),
mouseCursor:
mouseCursor ?? MaterialStateMouseCursor.clickable.resolve(states),
statesController: _statesController,
onToggled: widget.onChanged == null ? null : _onToggled,
);
}
Expand Down
26 changes: 23 additions & 3 deletions lib/src/widgets/yaru_switch_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,29 @@ class YaruSwitchButton extends StatefulWidget {
}

class _YaruSwitchButtonState extends State<YaruSwitchButton> {
final _statesController = MaterialStatesController();

@override
void initState() {
super.initState();
_statesController.update(MaterialState.disabled, widget.onChanged == null);
}

@override
void didUpdateWidget(YaruSwitchButton oldWidget) {
super.didUpdateWidget(oldWidget);
_statesController.update(MaterialState.disabled, widget.onChanged == null);
}

@override
void dispose() {
_statesController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
final states = {
if (widget.onChanged == null) MaterialState.disabled,
};
final states = _statesController.value;
final mouseCursor =
MaterialStateProperty.resolveAs(widget.mouseCursor, states) ??
YaruToggleButtonTheme.of(context)?.mouseCursor?.resolve(states);
Expand All @@ -67,9 +85,11 @@ class _YaruSwitchButtonState extends State<YaruSwitchButton> {
focusNode: widget.focusNode,
autofocus: widget.autofocus,
mouseCursor: mouseCursor,
statesController: _statesController,
),
mouseCursor:
mouseCursor ?? MaterialStateMouseCursor.clickable.resolve(states),
statesController: _statesController,
onToggled: widget.onChanged != null
? () => widget.onChanged!(!widget.value)
: null,
Expand Down
21 changes: 18 additions & 3 deletions lib/src/widgets/yaru_toggle_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class YaruToggleButton extends StatelessWidget {
this.contentPadding,
this.onToggled,
this.mouseCursor,
this.statesController,
});

/// The toggle indicator.
Expand All @@ -40,13 +41,15 @@ class YaruToggleButton extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the widget.
final MouseCursor? mouseCursor;

final MaterialStatesController? statesController;

@override
Widget build(BuildContext context) {
final theme = YaruToggleButtonTheme.of(context);
final textTheme = Theme.of(context).textTheme;
final states = {
if (onToggled == null) MaterialState.disabled,
};
final states = statesController?.value ??
{if (onToggled == null) MaterialState.disabled};
final enabled = !states.contains(MaterialState.disabled);
final mouseCursor =
MaterialStateProperty.resolveAs(this.mouseCursor, states) ??
MaterialStateMouseCursor.clickable.resolve(states);
Expand All @@ -55,8 +58,20 @@ class YaruToggleButton extends StatelessWidget {
child: Semantics(
child: GestureDetector(
onTap: onToggled,
onTapDown: (_) =>
statesController?.update(MaterialState.pressed, enabled),
onTapUp: (_) =>
statesController?.update(MaterialState.pressed, false),
onTapCancel: () =>
statesController?.update(MaterialState.pressed, false),
child: MouseRegion(
cursor: mouseCursor,
onEnter: (_) =>
statesController?.update(MaterialState.hovered, true),
onHover: (_) =>
statesController?.update(MaterialState.hovered, true),
onExit: (_) =>
statesController?.update(MaterialState.hovered, false),
child: Padding(
padding: contentPadding ?? EdgeInsets.zero,
child: _YaruToggleButtonLayout(
Expand Down

0 comments on commit 1dd727a

Please sign in to comment.