From f1900e18c85cdd10cb0629541a48727cba2ba013 Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Wed, 27 Nov 2024 11:35:26 +0100 Subject: [PATCH] Fix indeterminate state not working in Checkboxes (#705) The issue was that we weren't considering indeterminate as selected, icon-wise, but the IDE resources do consider it as such. --- foundation/api/foundation.api | 2 ++ .../foundation/state/ToggleableComponentState.kt | 3 +++ .../samples/standalone/view/component/Checkboxes.kt | 8 ++++---- ui/api/ui.api | 4 ++++ .../org/jetbrains/jewel/ui/component/Checkbox.kt | 7 +++++-- .../jewel/ui/component/styling/CheckboxStyling.kt | 12 ++++++------ 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/foundation/api/foundation.api b/foundation/api/foundation.api index 3db9a7e794..d2af70d029 100644 --- a/foundation/api/foundation.api +++ b/foundation/api/foundation.api @@ -872,6 +872,7 @@ public abstract interface class org/jetbrains/jewel/foundation/state/ToggleableC public static final field Companion Lorg/jetbrains/jewel/foundation/state/ToggleableComponentState$Companion; public abstract fun getToggleableState ()Landroidx/compose/ui/state/ToggleableState; public abstract fun isSelected ()Z + public abstract fun isSelectedOrIndeterminate ()Z } public final class org/jetbrains/jewel/foundation/state/ToggleableComponentState$Companion { @@ -880,6 +881,7 @@ public final class org/jetbrains/jewel/foundation/state/ToggleableComponentState public final class org/jetbrains/jewel/foundation/state/ToggleableComponentState$DefaultImpls { public static fun isSelected (Lorg/jetbrains/jewel/foundation/state/ToggleableComponentState;)Z + public static fun isSelectedOrIndeterminate (Lorg/jetbrains/jewel/foundation/state/ToggleableComponentState;)Z } public abstract interface class org/jetbrains/jewel/foundation/theme/JewelTheme { diff --git a/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt b/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt index 43d97d2585..16206eb7a4 100644 --- a/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt +++ b/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt @@ -10,6 +10,9 @@ public interface ToggleableComponentState { public val isSelected: Boolean get() = toggleableState == ToggleableState.On + public val isSelectedOrIndeterminate: Boolean + get() = toggleableState != ToggleableState.Off + public companion object { public fun ULong.readToggleableState(): ToggleableState { val selected = this and Selected != 0UL diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt index 8f729ff19d..54925fd99d 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt @@ -20,7 +20,7 @@ fun Checkboxes() { TriStateCheckboxRow( "Checkbox", checked, - { + onClick = { checked = when (checked) { ToggleableState.On -> ToggleableState.Off @@ -32,7 +32,7 @@ fun Checkboxes() { TriStateCheckboxRow( "Error", checked, - { + onClick = { checked = when (checked) { ToggleableState.On -> ToggleableState.Off @@ -45,7 +45,7 @@ fun Checkboxes() { TriStateCheckboxRow( "Warning", checked, - { + onClick = { checked = when (checked) { ToggleableState.On -> ToggleableState.Off @@ -55,6 +55,6 @@ fun Checkboxes() { }, outline = Outline.Warning, ) - TriStateCheckboxRow("Disabled", checked, {}, enabled = false) + TriStateCheckboxRow("Disabled", checked, onClick = {}, enabled = false) } } diff --git a/ui/api/ui.api b/ui/api/ui.api index 3cddc331a6..31d18b5235 100644 --- a/ui/api/ui.api +++ b/ui/api/ui.api @@ -184,6 +184,8 @@ public final class org/jetbrains/jewel/ui/component/CheckboxState : org/jetbrain public static fun isPressed-impl (J)Z public fun isSelected ()Z public static fun isSelected-impl (J)Z + public fun isSelectedOrIndeterminate ()Z + public static fun isSelectedOrIndeterminate-impl (J)Z public fun toString ()Ljava/lang/String; public static fun toString-impl (J)Ljava/lang/String; public final synthetic fun unbox-impl ()J @@ -1037,6 +1039,8 @@ public final class org/jetbrains/jewel/ui/component/ToggleableIconButtonState : public static fun isPressed-impl (J)Z public fun isSelected ()Z public static fun isSelected-impl (J)Z + public fun isSelectedOrIndeterminate ()Z + public static fun isSelectedOrIndeterminate-impl (J)Z public fun toString ()Ljava/lang/String; public static fun toString-impl (J)Ljava/lang/String; public final synthetic fun unbox-impl ()J diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt index 7c147822ee..d0898daad6 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt @@ -291,7 +291,10 @@ private fun CheckboxImpl( val wrapperModifier = modifier.triStateToggleable( state = state, - onClick = onClick, + onClick = { + onClick() + state + }, enabled = enabled, role = Role.Checkbox, interactionSource = interactionSource, @@ -315,7 +318,7 @@ private fun CheckboxImpl( } else { PainterHint.None }, - Selected(checkboxState.toggleableState == ToggleableState.On), + Selected(checkboxState.toggleableState != ToggleableState.Off), Stateful(checkboxState), ) diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt index d1d3c3b613..94812b0799 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt @@ -63,9 +63,9 @@ public class CheckboxMetrics( public fun outlineCornerSizeFor(state: CheckboxState): State = rememberUpdatedState( when { - state.isFocused && state.isSelected -> outlineSelectedFocusedCornerSize - !state.isFocused && state.isSelected -> outlineSelectedCornerSize - state.isFocused && !state.isSelected -> outlineFocusedCornerSize + state.isFocused && state.isSelectedOrIndeterminate -> outlineSelectedFocusedCornerSize + !state.isFocused && state.isSelectedOrIndeterminate -> outlineSelectedCornerSize + state.isFocused && !state.isSelectedOrIndeterminate -> outlineFocusedCornerSize else -> outlineCornerSize } ) @@ -74,9 +74,9 @@ public class CheckboxMetrics( public fun outlineSizeFor(state: CheckboxState): State = rememberUpdatedState( when { - state.isFocused && state.isSelected -> outlineSelectedFocusedSize - !state.isFocused && state.isSelected -> outlineSelectedSize - state.isFocused && !state.isSelected -> outlineFocusedSize + state.isFocused && state.isSelectedOrIndeterminate -> outlineSelectedFocusedSize + !state.isFocused && state.isSelectedOrIndeterminate -> outlineSelectedSize + state.isFocused && !state.isSelectedOrIndeterminate -> outlineFocusedSize else -> outlineSize } )