mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 22:51:17 +07:00
Create Slider component (#270)
Introduce Slider component following general IntUI style GitOrigin-RevId: 58b0402c3576be8fd2fe756626f661dde569c2b8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c616b98475
commit
fb31ac7ec1
@@ -73,6 +73,15 @@ public final class org/jetbrains/jewel/bridge/theme/BridgeGlobalMetricsKt {
|
||||
public static final fun readFromLaF (Lorg/jetbrains/jewel/foundation/GlobalMetrics$Companion;)Lorg/jetbrains/jewel/foundation/GlobalMetrics;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/bridge/theme/BridgeSliderStylingKt {
|
||||
public static final fun dark-7HESe_I (Lorg/jetbrains/jewel/ui/component/styling/SliderColors$Companion;JJJJJJJJJJJJJJJ)Lorg/jetbrains/jewel/ui/component/styling/SliderColors;
|
||||
public static synthetic fun dark-7HESe_I$default (Lorg/jetbrains/jewel/ui/component/styling/SliderColors$Companion;JJJJJJJJJJJJJJJILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/SliderColors;
|
||||
public static final fun defaults-IDSuZpE (Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics$Companion;FJFFFF)Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics;
|
||||
public static synthetic fun defaults-IDSuZpE$default (Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics$Companion;FJFFFFILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics;
|
||||
public static final fun light-7HESe_I (Lorg/jetbrains/jewel/ui/component/styling/SliderColors$Companion;JJJJJJJJJJJJJJJ)Lorg/jetbrains/jewel/ui/component/styling/SliderColors;
|
||||
public static synthetic fun light-7HESe_I$default (Lorg/jetbrains/jewel/ui/component/styling/SliderColors$Companion;JJJJJJJJJJJJJJJILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/SliderColors;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/bridge/theme/BridgeThemeColorPaletteKt {
|
||||
public static final fun getWindowsPopupBorder (Lorg/jetbrains/jewel/foundation/theme/ThemeColorPalette;)Landroidx/compose/ui/graphics/Color;
|
||||
public static final fun readFromLaF (Lorg/jetbrains/jewel/foundation/theme/ThemeColorPalette$Companion;)Lorg/jetbrains/jewel/foundation/theme/ThemeColorPalette;
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.jetbrains.jewel.bridge.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.takeOrElse
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.jewel.bridge.retrieveColorOrUnspecified
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderColors
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderMetrics
|
||||
|
||||
public fun SliderColors.Companion.light(
|
||||
track: Color = retrieveColorOrUnspecified("ColorPalette.Grey10").takeOrElse { Color(0xFFD3D5DB) },
|
||||
trackFilled: Color = retrieveColorOrUnspecified("ColorPalette.Blue6").takeOrElse { Color(0xFF588CF3) },
|
||||
trackDisabled: Color = retrieveColorOrUnspecified("ColorPalette.Grey12").takeOrElse { Color(0xFFEBECF0) },
|
||||
trackFilledDisabled: Color = retrieveColorOrUnspecified("ColorPalette.Grey11").takeOrElse { Color(0xFFDFE1E5) },
|
||||
stepMarker: Color = track,
|
||||
thumbFill: Color = retrieveColorOrUnspecified("ColorPalette.Grey14").takeOrElse { Color(0xFFFFFFFF) },
|
||||
thumbFillDisabled: Color = thumbFill,
|
||||
thumbFillFocused: Color = thumbFill,
|
||||
thumbFillPressed: Color = thumbFill,
|
||||
thumbFillHovered: Color = thumbFill,
|
||||
thumbBorder: Color = retrieveColorOrUnspecified("ColorPalette.Grey8").takeOrElse { Color(0xFFA8ADBD) },
|
||||
thumbBorderFocused: Color = retrieveColorOrUnspecified("ColorPalette.Blue4").takeOrElse { Color(0xFF3574F0) },
|
||||
thumbBorderDisabled: Color = retrieveColorOrUnspecified("ColorPalette.Grey11").takeOrElse { Color(0xFFDFE1E5) },
|
||||
thumbBorderPressed: Color = retrieveColorOrUnspecified("ColorPalette.Grey7").takeOrElse { Color(0xFF818594) },
|
||||
thumbBorderHovered: Color = retrieveColorOrUnspecified("ColorPalette.Grey9").takeOrElse { Color(0xFFC9CCD6) },
|
||||
): SliderColors = SliderColors(
|
||||
track,
|
||||
trackFilled,
|
||||
trackDisabled,
|
||||
trackFilledDisabled,
|
||||
stepMarker,
|
||||
thumbFill,
|
||||
thumbFillDisabled,
|
||||
thumbFillFocused,
|
||||
thumbFillPressed,
|
||||
thumbFillHovered,
|
||||
thumbBorder,
|
||||
thumbBorderFocused,
|
||||
thumbBorderDisabled,
|
||||
thumbBorderPressed,
|
||||
thumbBorderHovered,
|
||||
)
|
||||
|
||||
public fun SliderColors.Companion.dark(
|
||||
track: Color = retrieveColorOrUnspecified("ColorPalette.Grey4").takeOrElse { Color(0xFF43454A) },
|
||||
trackFilled: Color = retrieveColorOrUnspecified("ColorPalette.Blue7").takeOrElse { Color(0xFF467FF2) },
|
||||
trackDisabled: Color = retrieveColorOrUnspecified("ColorPalette.Grey3").takeOrElse { Color(0xFF393B40) },
|
||||
trackFilledDisabled: Color = retrieveColorOrUnspecified("ColorPalette.Grey4").takeOrElse { Color(0xFF43454A) },
|
||||
stepMarker: Color = track,
|
||||
thumbFill: Color = retrieveColorOrUnspecified("ColorPalette.Grey2").takeOrElse { Color(0xFF2B2D30) },
|
||||
thumbFillDisabled: Color = retrieveColorOrUnspecified("ColorPalette.Grey3").takeOrElse { Color(0xFF393B40) },
|
||||
thumbFillFocused: Color = thumbFill,
|
||||
thumbFillPressed: Color = thumbFill,
|
||||
thumbFillHovered: Color = thumbFill,
|
||||
thumbBorder: Color = retrieveColorOrUnspecified("ColorPalette.Grey7").takeOrElse { Color(0xFF6F737A) },
|
||||
thumbBorderFocused: Color = retrieveColorOrUnspecified("ColorPalette.Blue6").takeOrElse { Color(0xFF3574F0) },
|
||||
thumbBorderDisabled: Color = retrieveColorOrUnspecified("ColorPalette.Grey5").takeOrElse { Color(0xFF4E5157) },
|
||||
thumbBorderPressed: Color = retrieveColorOrUnspecified("ColorPalette.Grey8").takeOrElse { Color(0xFF868A91) },
|
||||
thumbBorderHovered: Color = retrieveColorOrUnspecified("ColorPalette.Grey9").takeOrElse { Color(0xFF9DA0A8) },
|
||||
): SliderColors = SliderColors(
|
||||
track,
|
||||
trackFilled,
|
||||
trackDisabled,
|
||||
trackFilledDisabled,
|
||||
stepMarker,
|
||||
thumbFill,
|
||||
thumbFillDisabled,
|
||||
thumbFillFocused,
|
||||
thumbFillPressed,
|
||||
thumbFillHovered,
|
||||
thumbBorder,
|
||||
thumbBorderFocused,
|
||||
thumbBorderDisabled,
|
||||
thumbBorderPressed,
|
||||
thumbBorderHovered,
|
||||
)
|
||||
|
||||
public fun SliderMetrics.Companion.defaults(
|
||||
trackHeight: Dp = 4.dp,
|
||||
thumbSize: DpSize = DpSize(14.dp, 14.dp),
|
||||
thumbBorderWidth: Dp = 1.dp,
|
||||
stepLineHeight: Dp = 8.dp,
|
||||
stepLineWidth: Dp = 1.dp,
|
||||
trackToStepSpacing: Dp = thumbSize.height / 2 + 4.dp,
|
||||
): SliderMetrics =
|
||||
SliderMetrics(trackHeight, thumbSize, thumbBorderWidth, stepLineHeight, stepLineWidth, trackToStepSpacing)
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jewel.bridge.theme
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.CornerSize
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
@@ -87,6 +88,9 @@ import org.jetbrains.jewel.ui.component.styling.RadioButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.ScrollbarColors
|
||||
import org.jetbrains.jewel.ui.component.styling.ScrollbarMetrics
|
||||
import org.jetbrains.jewel.ui.component.styling.ScrollbarStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderColors
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderMetrics
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.SubmenuMetrics
|
||||
import org.jetbrains.jewel.ui.component.styling.TabColors
|
||||
import org.jetbrains.jewel.ui.component.styling.TabContentAlpha
|
||||
@@ -178,6 +182,7 @@ internal fun createBridgeComponentStyling(
|
||||
outlinedButtonStyle = readOutlinedButtonStyle(),
|
||||
radioButtonStyle = readRadioButtonStyle(),
|
||||
scrollbarStyle = readScrollbarStyle(theme.isDark),
|
||||
sliderStyle = readSliderStyle(theme.isDark),
|
||||
textAreaStyle = readTextAreaStyle(textAreaTextStyle, textFieldStyle.metrics),
|
||||
textFieldStyle = textFieldStyle,
|
||||
tooltipStyle = readTooltipStyle(),
|
||||
@@ -627,6 +632,14 @@ private fun readScrollbarStyle(isDark: Boolean) =
|
||||
hoverDuration = 300.milliseconds,
|
||||
)
|
||||
|
||||
private fun readSliderStyle(dark: Boolean): SliderStyle {
|
||||
// There are no values for sliders in IntUi, so we're essentially reusing the
|
||||
// standalone colors logic, reading the palette values (and falling back to
|
||||
// hardcoded defaults).
|
||||
val colors = if (dark) SliderColors.dark() else SliderColors.light()
|
||||
return SliderStyle(colors, SliderMetrics.defaults(), CircleShape)
|
||||
}
|
||||
|
||||
private fun readTextAreaStyle(textStyle: TextStyle, metrics: TextFieldMetrics): TextAreaStyle {
|
||||
val normalBackground = retrieveColorOrUnspecified("TextArea.background")
|
||||
val normalContent = retrieveColorOrUnspecified("TextArea.foreground")
|
||||
|
||||
@@ -254,6 +254,14 @@ public final class org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarSt
|
||||
public static final fun light-RIQooxk (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJLandroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/intui/standalone/styling/IntUiSliderStylingKt {
|
||||
public static final fun dark (Lorg/jetbrains/jewel/ui/component/styling/SliderStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/SliderColors;Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;
|
||||
public static final fun dark-8v1krLo (Lorg/jetbrains/jewel/ui/component/styling/SliderColors$Companion;JJJJJJJJJJJJJJJLandroidx/compose/runtime/Composer;III)Lorg/jetbrains/jewel/ui/component/styling/SliderColors;
|
||||
public static final fun defaults-nDjVmYc (Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics$Companion;FJFFFFLandroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics;
|
||||
public static final fun light (Lorg/jetbrains/jewel/ui/component/styling/SliderStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/SliderColors;Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;
|
||||
public static final fun light-8v1krLo (Lorg/jetbrains/jewel/ui/component/styling/SliderColors$Companion;JJJJJJJJJJJJJJJLandroidx/compose/runtime/Composer;III)Lorg/jetbrains/jewel/ui/component/styling/SliderColors;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/intui/standalone/styling/IntUiTabStylingKt {
|
||||
public static final fun default (Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha$Companion;FFFFFFFFFF)Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha;
|
||||
public static synthetic fun default$default (Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha$Companion;FFFFFFFFFFILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha;
|
||||
@@ -325,11 +333,11 @@ public final class org/jetbrains/jewel/intui/standalone/theme/IntUiGlobalMetrics
|
||||
public final class org/jetbrains/jewel/intui/standalone/theme/IntUiThemeKt {
|
||||
public static final fun IntUiTheme (Lorg/jetbrains/jewel/foundation/theme/ThemeDefinition;Lorg/jetbrains/jewel/ui/ComponentStyling;ZLkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
|
||||
public static final fun IntUiTheme (ZZLkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
|
||||
public static final fun dark (Lorg/jetbrains/jewel/ui/ComponentStyling;Lorg/jetbrains/jewel/ui/component/styling/CheckboxStyle;Lorg/jetbrains/jewel/ui/component/styling/ChipStyle;Lorg/jetbrains/jewel/ui/component/styling/CircularProgressStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/GroupHeaderStyle;Lorg/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyle;Lorg/jetbrains/jewel/ui/component/styling/IconButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/LazyTreeStyle;Lorg/jetbrains/jewel/ui/component/styling/LinkStyle;Lorg/jetbrains/jewel/ui/component/styling/MenuStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Landroidx/compose/runtime/Composer;IIII)Lorg/jetbrains/jewel/ui/ComponentStyling;
|
||||
public static final fun dark (Lorg/jetbrains/jewel/ui/ComponentStyling;Lorg/jetbrains/jewel/ui/component/styling/CheckboxStyle;Lorg/jetbrains/jewel/ui/component/styling/ChipStyle;Lorg/jetbrains/jewel/ui/component/styling/CircularProgressStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/GroupHeaderStyle;Lorg/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyle;Lorg/jetbrains/jewel/ui/component/styling/IconButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/LazyTreeStyle;Lorg/jetbrains/jewel/ui/component/styling/LinkStyle;Lorg/jetbrains/jewel/ui/component/styling/MenuStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Landroidx/compose/runtime/Composer;IIII)Lorg/jetbrains/jewel/ui/ComponentStyling;
|
||||
public static final fun darkThemeDefinition-RFMEUTM (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Lorg/jetbrains/jewel/foundation/GlobalColors;Lorg/jetbrains/jewel/foundation/GlobalMetrics;Lorg/jetbrains/jewel/foundation/theme/ThemeColorPalette;Lorg/jetbrains/jewel/foundation/theme/ThemeIconData;Landroidx/compose/ui/text/TextStyle;JLandroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/foundation/theme/ThemeDefinition;
|
||||
public static final fun default (Lorg/jetbrains/jewel/ui/ComponentStyling;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/ComponentStyling;
|
||||
public static final fun getDefaultTextStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;)Landroidx/compose/ui/text/TextStyle;
|
||||
public static final fun light (Lorg/jetbrains/jewel/ui/ComponentStyling;Lorg/jetbrains/jewel/ui/component/styling/CheckboxStyle;Lorg/jetbrains/jewel/ui/component/styling/ChipStyle;Lorg/jetbrains/jewel/ui/component/styling/CircularProgressStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/GroupHeaderStyle;Lorg/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyle;Lorg/jetbrains/jewel/ui/component/styling/IconButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/LazyTreeStyle;Lorg/jetbrains/jewel/ui/component/styling/LinkStyle;Lorg/jetbrains/jewel/ui/component/styling/MenuStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Landroidx/compose/runtime/Composer;IIII)Lorg/jetbrains/jewel/ui/ComponentStyling;
|
||||
public static final fun light (Lorg/jetbrains/jewel/ui/ComponentStyling;Lorg/jetbrains/jewel/ui/component/styling/CheckboxStyle;Lorg/jetbrains/jewel/ui/component/styling/ChipStyle;Lorg/jetbrains/jewel/ui/component/styling/CircularProgressStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/GroupHeaderStyle;Lorg/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyle;Lorg/jetbrains/jewel/ui/component/styling/IconButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/LazyTreeStyle;Lorg/jetbrains/jewel/ui/component/styling/LinkStyle;Lorg/jetbrains/jewel/ui/component/styling/MenuStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Landroidx/compose/runtime/Composer;IIII)Lorg/jetbrains/jewel/ui/ComponentStyling;
|
||||
public static final fun lightThemeDefinition-RFMEUTM (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Lorg/jetbrains/jewel/foundation/GlobalColors;Lorg/jetbrains/jewel/foundation/GlobalMetrics;Lorg/jetbrains/jewel/foundation/theme/ThemeColorPalette;Lorg/jetbrains/jewel/foundation/theme/ThemeIconData;Landroidx/compose/ui/text/TextStyle;JLandroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/foundation/theme/ThemeDefinition;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package org.jetbrains.jewel.intui.standalone.styling
|
||||
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
|
||||
import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderColors
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderMetrics
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderStyle
|
||||
|
||||
@Composable
|
||||
public fun SliderStyle.Companion.light(
|
||||
colors: SliderColors = SliderColors.light(),
|
||||
metrics: SliderMetrics = SliderMetrics.defaults(),
|
||||
thumbShape: Shape = CircleShape,
|
||||
): SliderStyle = SliderStyle(colors, metrics, thumbShape)
|
||||
|
||||
@Composable
|
||||
public fun SliderStyle.Companion.dark(
|
||||
colors: SliderColors = SliderColors.dark(),
|
||||
metrics: SliderMetrics = SliderMetrics.defaults(),
|
||||
thumbShape: Shape = CircleShape,
|
||||
): SliderStyle = SliderStyle(colors, metrics, thumbShape)
|
||||
|
||||
@Composable
|
||||
public fun SliderColors.Companion.light(
|
||||
track: Color = IntUiLightTheme.colors.grey(10),
|
||||
trackFilled: Color = IntUiLightTheme.colors.blue(6),
|
||||
trackDisabled: Color = IntUiLightTheme.colors.grey(12),
|
||||
trackFilledDisabled: Color = IntUiLightTheme.colors.grey(11),
|
||||
stepMarker: Color = track,
|
||||
thumbFill: Color = IntUiLightTheme.colors.grey(14),
|
||||
thumbFillDisabled: Color = thumbFill,
|
||||
thumbFillFocused: Color = thumbFill,
|
||||
thumbFillPressed: Color = thumbFill,
|
||||
thumbFillHovered: Color = thumbFill,
|
||||
thumbBorder: Color = IntUiLightTheme.colors.grey(8),
|
||||
thumbBorderFocused: Color = IntUiLightTheme.colors.blue(4),
|
||||
thumbBorderDisabled: Color = IntUiLightTheme.colors.grey(11),
|
||||
thumbBorderPressed: Color = IntUiLightTheme.colors.grey(7),
|
||||
thumbBorderHovered: Color = IntUiLightTheme.colors.grey(9),
|
||||
): SliderColors = SliderColors(
|
||||
track,
|
||||
trackFilled,
|
||||
trackDisabled,
|
||||
trackFilledDisabled,
|
||||
stepMarker,
|
||||
thumbFill,
|
||||
thumbFillDisabled,
|
||||
thumbFillFocused,
|
||||
thumbFillPressed,
|
||||
thumbFillHovered,
|
||||
thumbBorder,
|
||||
thumbBorderFocused,
|
||||
thumbBorderDisabled,
|
||||
thumbBorderPressed,
|
||||
thumbBorderHovered,
|
||||
)
|
||||
|
||||
@Composable
|
||||
public fun SliderColors.Companion.dark(
|
||||
track: Color = IntUiDarkTheme.colors.grey(4),
|
||||
trackFilled: Color = IntUiDarkTheme.colors.blue(7),
|
||||
trackDisabled: Color = IntUiDarkTheme.colors.grey(3),
|
||||
trackFilledDisabled: Color = IntUiDarkTheme.colors.grey(4),
|
||||
stepMarker: Color = track,
|
||||
thumbFill: Color = IntUiDarkTheme.colors.grey(2),
|
||||
thumbFillDisabled: Color = IntUiDarkTheme.colors.grey(3),
|
||||
thumbFillFocused: Color = thumbFill,
|
||||
thumbFillPressed: Color = thumbFill,
|
||||
thumbFillHovered: Color = thumbFill,
|
||||
thumbBorder: Color = IntUiDarkTheme.colors.grey(7),
|
||||
thumbBorderFocused: Color = IntUiDarkTheme.colors.blue(6),
|
||||
thumbBorderDisabled: Color = IntUiDarkTheme.colors.grey(5),
|
||||
thumbBorderPressed: Color = IntUiDarkTheme.colors.grey(8),
|
||||
thumbBorderHovered: Color = IntUiDarkTheme.colors.grey(9),
|
||||
): SliderColors = SliderColors(
|
||||
track,
|
||||
trackFilled,
|
||||
trackDisabled,
|
||||
trackFilledDisabled,
|
||||
stepMarker,
|
||||
thumbFill,
|
||||
thumbFillDisabled,
|
||||
thumbFillFocused,
|
||||
thumbFillPressed,
|
||||
thumbFillHovered,
|
||||
thumbBorder,
|
||||
thumbBorderFocused,
|
||||
thumbBorderDisabled,
|
||||
thumbBorderPressed,
|
||||
thumbBorderHovered,
|
||||
)
|
||||
|
||||
@Composable
|
||||
public fun SliderMetrics.Companion.defaults(
|
||||
trackHeight: Dp = 4.dp,
|
||||
thumbSize: DpSize = DpSize(14.dp, 14.dp),
|
||||
thumbBorderWidth: Dp = 1.dp,
|
||||
stepLineHeight: Dp = 8.dp,
|
||||
stepLineWidth: Dp = 1.dp,
|
||||
trackToStepSpacing: Dp = thumbSize.height / 2 + 4.dp,
|
||||
): SliderMetrics =
|
||||
SliderMetrics(trackHeight, thumbSize, thumbBorderWidth, stepLineHeight, stepLineWidth, trackToStepSpacing)
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.jewel.ui.component.styling.LinkStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.MenuStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.RadioButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.ScrollbarStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TabStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TextAreaStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TextFieldStyle
|
||||
@@ -102,6 +103,7 @@ public fun ComponentStyling.dark(
|
||||
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(),
|
||||
radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(),
|
||||
scrollbarStyle: ScrollbarStyle = ScrollbarStyle.dark(),
|
||||
sliderStyle: SliderStyle = SliderStyle.dark(),
|
||||
textAreaStyle: TextAreaStyle = TextAreaStyle.dark(),
|
||||
textFieldStyle: TextFieldStyle = TextFieldStyle.dark(),
|
||||
tooltipStyle: TooltipStyle = TooltipStyle.dark(),
|
||||
@@ -126,6 +128,7 @@ public fun ComponentStyling.dark(
|
||||
outlinedButtonStyle = outlinedButtonStyle,
|
||||
radioButtonStyle = radioButtonStyle,
|
||||
scrollbarStyle = scrollbarStyle,
|
||||
sliderStyle = sliderStyle,
|
||||
textAreaStyle = textAreaStyle,
|
||||
textFieldStyle = textFieldStyle,
|
||||
tooltipStyle = tooltipStyle,
|
||||
@@ -152,6 +155,7 @@ public fun ComponentStyling.light(
|
||||
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(),
|
||||
radioButtonStyle: RadioButtonStyle = RadioButtonStyle.light(),
|
||||
scrollbarStyle: ScrollbarStyle = ScrollbarStyle.light(),
|
||||
sliderStyle: SliderStyle = SliderStyle.light(),
|
||||
textAreaStyle: TextAreaStyle = TextAreaStyle.light(),
|
||||
textFieldStyle: TextFieldStyle = TextFieldStyle.light(),
|
||||
tooltipStyle: TooltipStyle = TooltipStyle.light(),
|
||||
@@ -176,6 +180,7 @@ public fun ComponentStyling.light(
|
||||
outlinedButtonStyle = outlinedButtonStyle,
|
||||
radioButtonStyle = radioButtonStyle,
|
||||
scrollbarStyle = scrollbarStyle,
|
||||
sliderStyle = sliderStyle,
|
||||
textAreaStyle = textAreaStyle,
|
||||
textFieldStyle = textFieldStyle,
|
||||
tooltipStyle = tooltipStyle,
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.intellij.icons.AllIcons
|
||||
import com.intellij.ui.JBColor
|
||||
import icons.JewelIcons
|
||||
import org.jetbrains.jewel.bridge.LocalComponent
|
||||
import org.jetbrains.jewel.bridge.ToolWindowScope
|
||||
import org.jetbrains.jewel.bridge.toComposeColor
|
||||
import org.jetbrains.jewel.foundation.lazy.tree.buildTree
|
||||
import org.jetbrains.jewel.foundation.modifier.onActivated
|
||||
@@ -43,12 +42,13 @@ import org.jetbrains.jewel.ui.component.IconButton
|
||||
import org.jetbrains.jewel.ui.component.LazyTree
|
||||
import org.jetbrains.jewel.ui.component.OutlinedButton
|
||||
import org.jetbrains.jewel.ui.component.RadioButtonRow
|
||||
import org.jetbrains.jewel.ui.component.Slider
|
||||
import org.jetbrains.jewel.ui.component.Text
|
||||
import org.jetbrains.jewel.ui.component.TextField
|
||||
import org.jetbrains.jewel.ui.component.Tooltip
|
||||
|
||||
@Composable
|
||||
internal fun ToolWindowScope.ComponentShowcaseTab() {
|
||||
internal fun ComponentShowcaseTab() {
|
||||
val bgColor by remember(JewelTheme.isDark) { mutableStateOf(JBColor.PanelBackground.toComposeColor()) }
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
@@ -178,6 +178,9 @@ private fun RowScope.ColumnOne() {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var sliderValue by remember { mutableStateOf(.15f) }
|
||||
Slider(sliderValue, { sliderValue = it }, steps = 5)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.jetbrains.jewel.samples.standalone.view.component
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import org.jetbrains.jewel.samples.standalone.viewmodel.View
|
||||
import org.jetbrains.jewel.ui.component.Slider
|
||||
|
||||
@Composable
|
||||
@View(title = "Sliders", position = 12)
|
||||
fun Sliders() {
|
||||
var value1 by remember { mutableStateOf(.45f) }
|
||||
Slider(
|
||||
value = value1,
|
||||
onValueChange = { value1 = it },
|
||||
)
|
||||
|
||||
var value2 by remember { mutableStateOf(.7f) }
|
||||
Slider(
|
||||
value = value2,
|
||||
onValueChange = { value2 = it },
|
||||
enabled = false,
|
||||
)
|
||||
|
||||
var value3 by remember { mutableStateOf(33f) }
|
||||
Slider(
|
||||
value = value3,
|
||||
onValueChange = { value3 = it },
|
||||
steps = 10,
|
||||
valueRange = 0f..100f,
|
||||
)
|
||||
|
||||
var value4 by remember { mutableStateOf(23f) }
|
||||
Slider(
|
||||
value = value4,
|
||||
onValueChange = { value4 = it },
|
||||
steps = 10,
|
||||
valueRange = 0f..100f,
|
||||
enabled = false,
|
||||
)
|
||||
}
|
||||
@@ -25,7 +25,7 @@ public final class org/jetbrains/jewel/ui/ComponentStyling$DefaultImpls {
|
||||
|
||||
public final class org/jetbrains/jewel/ui/DefaultComponentStyling : org/jetbrains/jewel/ui/ComponentStyling {
|
||||
public static final field $stable I
|
||||
public fun <init> (Lorg/jetbrains/jewel/ui/component/styling/CheckboxStyle;Lorg/jetbrains/jewel/ui/component/styling/ChipStyle;Lorg/jetbrains/jewel/ui/component/styling/CircularProgressStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/GroupHeaderStyle;Lorg/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyle;Lorg/jetbrains/jewel/ui/component/styling/IconButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/LazyTreeStyle;Lorg/jetbrains/jewel/ui/component/styling/LinkStyle;Lorg/jetbrains/jewel/ui/component/styling/MenuStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;)V
|
||||
public fun <init> (Lorg/jetbrains/jewel/ui/component/styling/CheckboxStyle;Lorg/jetbrains/jewel/ui/component/styling/ChipStyle;Lorg/jetbrains/jewel/ui/component/styling/CircularProgressStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;Lorg/jetbrains/jewel/ui/component/styling/TabStyle;Lorg/jetbrains/jewel/ui/component/styling/GroupHeaderStyle;Lorg/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyle;Lorg/jetbrains/jewel/ui/component/styling/IconButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/LazyTreeStyle;Lorg/jetbrains/jewel/ui/component/styling/LinkStyle;Lorg/jetbrains/jewel/ui/component/styling/MenuStyle;Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;Lorg/jetbrains/jewel/ui/component/styling/DropdownStyle;)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getCheckboxStyle ()Lorg/jetbrains/jewel/ui/component/styling/CheckboxStyle;
|
||||
public final fun getChipStyle ()Lorg/jetbrains/jewel/ui/component/styling/ChipStyle;
|
||||
@@ -44,6 +44,7 @@ public final class org/jetbrains/jewel/ui/DefaultComponentStyling : org/jetbrain
|
||||
public final fun getOutlinedButtonStyle ()Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;
|
||||
public final fun getRadioButtonStyle ()Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;
|
||||
public final fun getScrollbarStyle ()Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;
|
||||
public final fun getSliderStyle ()Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;
|
||||
public final fun getTextAreaStyle ()Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;
|
||||
public final fun getTextFieldStyle ()Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;
|
||||
public final fun getTooltipStyle ()Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;
|
||||
@@ -551,6 +552,44 @@ public final class org/jetbrains/jewel/ui/component/ScrollbarsKt {
|
||||
public static final fun VerticalScrollbar (Landroidx/compose/foundation/v2/ScrollbarAdapter;Landroidx/compose/ui/Modifier;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Landroidx/compose/runtime/Composer;II)V
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/SliderKt {
|
||||
public static final fun Slider (FLkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;ZLkotlin/ranges/ClosedFloatingPointRange;ILkotlin/jvm/functions/Function0;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;Landroidx/compose/runtime/Composer;II)V
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/SliderState : org/jetbrains/jewel/foundation/state/FocusableComponentState {
|
||||
public static final field Companion Lorg/jetbrains/jewel/ui/component/SliderState$Companion;
|
||||
public static final synthetic fun box-impl (J)Lorg/jetbrains/jewel/ui/component/SliderState;
|
||||
public fun chooseValue (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Ljava/lang/Object;
|
||||
public static fun chooseValue-impl (JLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Ljava/lang/Object;
|
||||
public static fun constructor-impl (J)J
|
||||
public static final fun copy-GPhM_18 (JZZZZZ)J
|
||||
public static synthetic fun copy-GPhM_18$default (JZZZZZILjava/lang/Object;)J
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public static fun equals-impl (JLjava/lang/Object;)Z
|
||||
public static final fun equals-impl0 (JJ)Z
|
||||
public final fun getState-s-VKNKU ()J
|
||||
public fun hashCode ()I
|
||||
public static fun hashCode-impl (J)I
|
||||
public fun isActive ()Z
|
||||
public static fun isActive-impl (J)Z
|
||||
public fun isEnabled ()Z
|
||||
public static fun isEnabled-impl (J)Z
|
||||
public fun isFocused ()Z
|
||||
public static fun isFocused-impl (J)Z
|
||||
public fun isHovered ()Z
|
||||
public static fun isHovered-impl (J)Z
|
||||
public fun isPressed ()Z
|
||||
public static fun isPressed-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
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/SliderState$Companion {
|
||||
public final fun of-GPhM_18 (ZZZZZ)J
|
||||
public static synthetic fun of-GPhM_18$default (Lorg/jetbrains/jewel/ui/component/SliderState$Companion;ZZZZZILjava/lang/Object;)J
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/SplitLayoutKt {
|
||||
public static final fun HorizontalSplitLayout-BssWTFQ (Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/ui/Modifier;JFFFFFFLandroidx/compose/runtime/Composer;II)V
|
||||
public static final fun VerticalSplitLayout-BssWTFQ (Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/ui/Modifier;JFFFFFFLandroidx/compose/runtime/Composer;II)V
|
||||
@@ -1637,6 +1676,72 @@ public final class org/jetbrains/jewel/ui/component/styling/ScrollbarStylingKt {
|
||||
public static final fun getLocalScrollbarStyle ()Landroidx/compose/runtime/ProvidableCompositionLocal;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SliderColors {
|
||||
public static final field $stable I
|
||||
public static final field Companion Lorg/jetbrains/jewel/ui/component/styling/SliderColors$Companion;
|
||||
public synthetic fun <init> (JJJJJJJJJJJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getStepMarker-0d7_KjU ()J
|
||||
public final fun getThumbBorder-0d7_KjU ()J
|
||||
public final fun getThumbBorderDisabled-0d7_KjU ()J
|
||||
public final fun getThumbBorderFocused-0d7_KjU ()J
|
||||
public final fun getThumbBorderHovered-0d7_KjU ()J
|
||||
public final fun getThumbBorderPressed-0d7_KjU ()J
|
||||
public final fun getThumbFill-0d7_KjU ()J
|
||||
public final fun getThumbFillDisabled-0d7_KjU ()J
|
||||
public final fun getThumbFillFocused-0d7_KjU ()J
|
||||
public final fun getThumbFillHovered-0d7_KjU ()J
|
||||
public final fun getThumbFillPressed-0d7_KjU ()J
|
||||
public final fun getTrack-0d7_KjU ()J
|
||||
public final fun getTrackDisabled-0d7_KjU ()J
|
||||
public final fun getTrackFilled-0d7_KjU ()J
|
||||
public final fun getTrackFilledDisabled-0d7_KjU ()J
|
||||
public fun hashCode ()I
|
||||
public final fun thumbBorderFor-p6gmeQ4 (JLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
|
||||
public final fun thumbFillFor-p6gmeQ4 (JLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SliderColors$Companion {
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SliderMetrics {
|
||||
public static final field $stable I
|
||||
public static final field Companion Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics$Companion;
|
||||
public synthetic fun <init> (FJFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getStepLineHeight-D9Ej5fM ()F
|
||||
public final fun getStepLineWidth-D9Ej5fM ()F
|
||||
public final fun getThumbBorderWidth-D9Ej5fM ()F
|
||||
public final fun getThumbSize-MYxV2XQ ()J
|
||||
public final fun getTrackHeight-D9Ej5fM ()F
|
||||
public final fun getTrackToStepSpacing-D9Ej5fM ()F
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SliderMetrics$Companion {
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SliderStyle {
|
||||
public static final field $stable I
|
||||
public static final field Companion Lorg/jetbrains/jewel/ui/component/styling/SliderStyle$Companion;
|
||||
public fun <init> (Lorg/jetbrains/jewel/ui/component/styling/SliderColors;Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics;Landroidx/compose/ui/graphics/Shape;)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getColors ()Lorg/jetbrains/jewel/ui/component/styling/SliderColors;
|
||||
public final fun getMetrics ()Lorg/jetbrains/jewel/ui/component/styling/SliderMetrics;
|
||||
public final fun getThumbShape ()Landroidx/compose/ui/graphics/Shape;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SliderStyle$Companion {
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SliderStylingKt {
|
||||
public static final fun getLocalSliderStyle ()Landroidx/compose/runtime/ProvidableCompositionLocal;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/jewel/ui/component/styling/SubmenuMetrics {
|
||||
public static final field $stable I
|
||||
public static final field Companion Lorg/jetbrains/jewel/ui/component/styling/SubmenuMetrics$Companion;
|
||||
@@ -2197,6 +2302,7 @@ public final class org/jetbrains/jewel/ui/theme/JewelThemeKt {
|
||||
public static final fun getOutlinedButtonStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/component/styling/ButtonStyle;
|
||||
public static final fun getRadioButtonStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/component/styling/RadioButtonStyle;
|
||||
public static final fun getScrollbarStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;
|
||||
public static final fun getSliderStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/component/styling/SliderStyle;
|
||||
public static final fun getTextAreaStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;
|
||||
public static final fun getTextFieldStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;
|
||||
public static final fun getTooltipStyle (Lorg/jetbrains/jewel/foundation/theme/JewelTheme$Companion;Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/ui/component/styling/TooltipStyle;
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.jewel.ui.component.styling.LocalMenuStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalOutlinedButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalRadioButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalScrollbarStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalSliderStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalTextAreaStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalTextFieldStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalTooltipStyle
|
||||
@@ -41,6 +42,7 @@ import org.jetbrains.jewel.ui.component.styling.LocalUndecoratedDropdownStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.MenuStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.RadioButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.ScrollbarStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TabStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TextAreaStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TextFieldStyle
|
||||
@@ -66,6 +68,7 @@ public class DefaultComponentStyling(
|
||||
public val outlinedButtonStyle: ButtonStyle,
|
||||
public val radioButtonStyle: RadioButtonStyle,
|
||||
public val scrollbarStyle: ScrollbarStyle,
|
||||
public val sliderStyle: SliderStyle,
|
||||
public val textAreaStyle: TextAreaStyle,
|
||||
public val textFieldStyle: TextFieldStyle,
|
||||
public val tooltipStyle: TooltipStyle,
|
||||
@@ -93,6 +96,7 @@ public class DefaultComponentStyling(
|
||||
LocalOutlinedButtonStyle provides outlinedButtonStyle,
|
||||
LocalRadioButtonStyle provides radioButtonStyle,
|
||||
LocalScrollbarStyle provides scrollbarStyle,
|
||||
LocalSliderStyle provides sliderStyle,
|
||||
LocalTextAreaStyle provides textAreaStyle,
|
||||
LocalTextFieldStyle provides textFieldStyle,
|
||||
LocalTooltipStyle provides tooltipStyle,
|
||||
|
||||
@@ -94,8 +94,9 @@ private fun ButtonImpl(
|
||||
textStyle: TextStyle,
|
||||
content: @Composable RowScope.() -> Unit,
|
||||
) {
|
||||
var buttonState by
|
||||
remember(interactionSource) { mutableStateOf(ButtonState.of(enabled = enabled)) }
|
||||
var buttonState by remember(interactionSource) {
|
||||
mutableStateOf(ButtonState.of(enabled = enabled))
|
||||
}
|
||||
|
||||
remember(enabled) { buttonState = buttonState.copy(enabled = enabled) }
|
||||
|
||||
@@ -103,9 +104,9 @@ private fun ButtonImpl(
|
||||
interactionSource.interactions.collect { interaction ->
|
||||
when (interaction) {
|
||||
is PressInteraction.Press -> buttonState = buttonState.copy(pressed = true)
|
||||
is PressInteraction.Cancel,
|
||||
is PressInteraction.Release,
|
||||
-> buttonState = buttonState.copy(pressed = false)
|
||||
is PressInteraction.Cancel, is PressInteraction.Release ->
|
||||
buttonState = buttonState.copy(pressed = false)
|
||||
|
||||
is HoverInteraction.Enter -> buttonState = buttonState.copy(hovered = true)
|
||||
is HoverInteraction.Exit -> buttonState = buttonState.copy(hovered = false)
|
||||
is FocusInteraction.Focus -> buttonState = buttonState.copy(focused = true)
|
||||
|
||||
@@ -0,0 +1,735 @@
|
||||
package org.jetbrains.jewel.ui.component
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.TweenSpec
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.MutatePriority
|
||||
import androidx.compose.foundation.MutatorMutex
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.focusable
|
||||
import androidx.compose.foundation.gestures.DragScope
|
||||
import androidx.compose.foundation.gestures.DraggableState
|
||||
import androidx.compose.foundation.gestures.GestureCancellationException
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.gestures.draggable
|
||||
import androidx.compose.foundation.hoverable
|
||||
import androidx.compose.foundation.interaction.DragInteraction
|
||||
import androidx.compose.foundation.interaction.FocusInteraction
|
||||
import androidx.compose.foundation.interaction.HoverInteraction
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.PressInteraction
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredSizeIn
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.progressSemantics
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.lerp
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.input.key.KeyEvent
|
||||
import androidx.compose.ui.input.key.KeyEventType
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.key.nativeKeyCode
|
||||
import androidx.compose.ui.input.key.onKeyEvent
|
||||
import androidx.compose.ui.input.key.type
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.platform.debugInspectorInfo
|
||||
import androidx.compose.ui.semantics.disabled
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.setProgress
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.jewel.foundation.Stroke
|
||||
import org.jetbrains.jewel.foundation.modifier.border
|
||||
import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Active
|
||||
import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Enabled
|
||||
import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Focused
|
||||
import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Hovered
|
||||
import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Pressed
|
||||
import org.jetbrains.jewel.foundation.state.FocusableComponentState
|
||||
import org.jetbrains.jewel.foundation.theme.JewelTheme
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderStyle
|
||||
import org.jetbrains.jewel.ui.focusOutline
|
||||
import org.jetbrains.jewel.ui.theme.sliderStyle
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
// Note: a lot of code in this file is from the Material 2 implementation
|
||||
|
||||
@Composable
|
||||
public fun Slider(
|
||||
value: Float,
|
||||
onValueChange: (Float) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
|
||||
steps: Int = 0,
|
||||
onValueChangeFinished: (() -> Unit)? = null,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
style: SliderStyle = JewelTheme.sliderStyle,
|
||||
) {
|
||||
require(steps >= 0) { "The number of steps must be >= 0" }
|
||||
|
||||
val onValueChangeState = rememberUpdatedState(onValueChange)
|
||||
val onValueChangeFinishedState = rememberUpdatedState(onValueChangeFinished)
|
||||
val tickFractions = remember(steps) {
|
||||
stepsToTickFractions(steps)
|
||||
}
|
||||
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
|
||||
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val thumbSize = style.metrics.thumbSize
|
||||
val ticksHeight = if (tickFractions.isNotEmpty()) {
|
||||
style.metrics.trackToStepSpacing + style.metrics.stepLineHeight
|
||||
} else {
|
||||
0.dp
|
||||
}
|
||||
|
||||
val minHeight = thumbSize.height + style.metrics.thumbBorderWidth * 2 + ticksHeight
|
||||
|
||||
BoxWithConstraints(
|
||||
modifier
|
||||
.requiredSizeIn(minWidth = thumbSize.height * 2, minHeight = minHeight)
|
||||
.sliderSemantics(value, enabled, onValueChange, onValueChangeFinished, valueRange, steps)
|
||||
.focusRequester(focusRequester)
|
||||
.focusable(enabled, interactionSource)
|
||||
.slideOnKeyEvents(enabled, steps, valueRange, value, isRtl, onValueChangeState, onValueChangeFinishedState),
|
||||
) {
|
||||
val widthPx = constraints.maxWidth.toFloat()
|
||||
val maxPx: Float
|
||||
val minPx: Float
|
||||
|
||||
with(LocalDensity.current) {
|
||||
maxPx = max(widthPx - thumbSize.width.toPx(), 0f)
|
||||
minPx = min(thumbSize.width.toPx(), maxPx)
|
||||
}
|
||||
|
||||
fun scaleToUserValue(offset: Float) =
|
||||
scale(minPx, maxPx, offset, valueRange.start, valueRange.endInclusive)
|
||||
|
||||
fun scaleToOffset(userValue: Float) =
|
||||
scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val rawOffset = remember { mutableFloatStateOf(scaleToOffset(value)) }
|
||||
val pressOffset = remember { mutableFloatStateOf(0f) }
|
||||
|
||||
val draggableState = remember(minPx, maxPx, valueRange) {
|
||||
SliderDraggableState {
|
||||
rawOffset.floatValue = (rawOffset.floatValue + it + pressOffset.floatValue)
|
||||
pressOffset.floatValue = 0f
|
||||
val offsetInTrack = rawOffset.floatValue.coerceIn(minPx, maxPx)
|
||||
onValueChangeState.value.invoke(scaleToUserValue(offsetInTrack))
|
||||
}
|
||||
}
|
||||
|
||||
CorrectValueSideEffect(::scaleToOffset, valueRange, minPx..maxPx, rawOffset, value)
|
||||
|
||||
val canAnimate = !JewelTheme.isSwingCompatMode
|
||||
val gestureEndAction = rememberUpdatedState<(Float) -> Unit> { velocity: Float ->
|
||||
val current = rawOffset.floatValue
|
||||
val target = snapValueToTick(current, tickFractions, minPx, maxPx)
|
||||
focusRequester.requestFocus()
|
||||
if (current != target) {
|
||||
scope.launch {
|
||||
if (canAnimate) {
|
||||
animateToTarget(draggableState, current, target, velocity)
|
||||
} else {
|
||||
draggableState.drag {
|
||||
dragBy(target - current)
|
||||
}
|
||||
}
|
||||
onValueChangeFinished?.invoke()
|
||||
}
|
||||
} else if (!draggableState.isDragging) {
|
||||
// check ifDragging in case the change is still in progress (touch -> drag case)
|
||||
onValueChangeFinished?.invoke()
|
||||
}
|
||||
}
|
||||
val press = Modifier.sliderTapModifier(
|
||||
draggableState,
|
||||
interactionSource,
|
||||
widthPx,
|
||||
isRtl,
|
||||
rawOffset,
|
||||
gestureEndAction,
|
||||
pressOffset,
|
||||
enabled,
|
||||
)
|
||||
|
||||
val drag = Modifier.draggable(
|
||||
orientation = Orientation.Horizontal,
|
||||
reverseDirection = isRtl,
|
||||
enabled = enabled,
|
||||
interactionSource = interactionSource,
|
||||
onDragStopped = { velocity -> gestureEndAction.value.invoke(velocity) },
|
||||
startDragImmediately = draggableState.isDragging,
|
||||
state = draggableState,
|
||||
)
|
||||
|
||||
val coerced = value.coerceIn(valueRange.start, valueRange.endInclusive)
|
||||
val fraction = calcFraction(valueRange.start, valueRange.endInclusive, coerced)
|
||||
SliderImpl(
|
||||
enabled = enabled,
|
||||
positionFraction = fraction,
|
||||
tickFractions = tickFractions,
|
||||
style = style,
|
||||
minHeight = minHeight,
|
||||
width = maxPx - minPx,
|
||||
interactionSource = interactionSource,
|
||||
modifier = press.then(drag),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val SliderMinWidth = 100.dp // Completely arbitrary
|
||||
|
||||
@Composable
|
||||
private fun SliderImpl(
|
||||
enabled: Boolean,
|
||||
positionFraction: Float,
|
||||
tickFractions: List<Float>,
|
||||
style: SliderStyle,
|
||||
width: Float,
|
||||
minHeight: Dp,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier.then(
|
||||
Modifier
|
||||
.widthIn(min = SliderMinWidth)
|
||||
.heightIn(min = minHeight),
|
||||
),
|
||||
) {
|
||||
val widthDp: Dp
|
||||
with(LocalDensity.current) {
|
||||
widthDp = width.toDp()
|
||||
}
|
||||
|
||||
Track(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = style,
|
||||
enabled = enabled,
|
||||
positionFractionEnd = positionFraction,
|
||||
tickFractions = tickFractions,
|
||||
)
|
||||
|
||||
val offset = (widthDp + style.metrics.thumbSize.width) * positionFraction
|
||||
SliderThumb(offset, interactionSource, style, enabled)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Track(
|
||||
modifier: Modifier,
|
||||
style: SliderStyle,
|
||||
enabled: Boolean,
|
||||
positionFractionEnd: Float,
|
||||
tickFractions: List<Float>,
|
||||
) {
|
||||
val trackStrokeWidthPx: Float
|
||||
val thumbWidthPx: Float
|
||||
val trackYPx: Float
|
||||
val stepLineHeightPx: Float
|
||||
val stepLineWidthPx: Float
|
||||
val trackToMarkersGapPx: Float
|
||||
|
||||
with(LocalDensity.current) {
|
||||
trackStrokeWidthPx = style.metrics.trackHeight.toPx()
|
||||
thumbWidthPx = style.metrics.thumbSize.width.toPx()
|
||||
trackYPx = style.metrics.thumbSize.width.toPx() / 2 + style.metrics.thumbBorderWidth.toPx()
|
||||
stepLineHeightPx = style.metrics.stepLineHeight.toPx()
|
||||
stepLineWidthPx = style.metrics.stepLineWidth.toPx()
|
||||
trackToMarkersGapPx = style.metrics.trackToStepSpacing.toPx()
|
||||
}
|
||||
|
||||
Canvas(modifier) {
|
||||
val isRtl = layoutDirection == LayoutDirection.Rtl
|
||||
|
||||
val trackLeft = Offset(thumbWidthPx / 2, trackYPx)
|
||||
val trackRight = Offset(size.width - thumbWidthPx / 2, trackYPx)
|
||||
val trackStart = if (isRtl) trackRight else trackLeft
|
||||
val trackEnd = if (isRtl) trackLeft else trackRight
|
||||
|
||||
drawLine(
|
||||
color = if (enabled) style.colors.track else style.colors.trackDisabled,
|
||||
start = trackStart,
|
||||
end = trackEnd,
|
||||
strokeWidth = trackStrokeWidthPx,
|
||||
cap = StrokeCap.Round,
|
||||
)
|
||||
|
||||
val activeTrackStart = Offset(trackStart.x, trackYPx)
|
||||
val activeTrackEnd = Offset(
|
||||
x = trackStart.x + (trackEnd.x - trackStart.x) * positionFractionEnd - thumbWidthPx / 2,
|
||||
y = trackYPx,
|
||||
)
|
||||
|
||||
drawLine(
|
||||
color = if (enabled) style.colors.trackFilled else style.colors.trackFilledDisabled,
|
||||
start = activeTrackStart,
|
||||
end = activeTrackEnd,
|
||||
strokeWidth = trackStrokeWidthPx,
|
||||
cap = StrokeCap.Round,
|
||||
)
|
||||
|
||||
val stepMarkerY = trackStrokeWidthPx + trackToMarkersGapPx
|
||||
|
||||
tickFractions.forEach { fraction ->
|
||||
drawLine(
|
||||
color = style.colors.stepMarker,
|
||||
start = Offset(lerp(trackStart, trackEnd, fraction).x, stepMarkerY),
|
||||
end = Offset(lerp(trackStart, trackEnd, fraction).x, stepMarkerY + stepLineHeightPx),
|
||||
strokeWidth = stepLineWidthPx,
|
||||
cap = StrokeCap.Round,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BoxScope.SliderThumb(
|
||||
offset: Dp,
|
||||
interactionSource: MutableInteractionSource,
|
||||
style: SliderStyle,
|
||||
enabled: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.padding(start = offset, top = style.metrics.thumbBorderWidth)
|
||||
.align(Alignment.TopStart),
|
||||
) {
|
||||
var state by remember { mutableStateOf(SliderState.of(enabled)) }
|
||||
remember(enabled) { state = state.copy(enabled = enabled) }
|
||||
|
||||
LaunchedEffect(interactionSource) {
|
||||
interactionSource.interactions.collect { interaction ->
|
||||
when (interaction) {
|
||||
is PressInteraction.Press, is DragInteraction.Start ->
|
||||
state = state.copy(pressed = true)
|
||||
|
||||
is PressInteraction.Release, is PressInteraction.Cancel,
|
||||
is DragInteraction.Stop, is DragInteraction.Cancel,
|
||||
->
|
||||
state = state.copy(pressed = false)
|
||||
|
||||
is HoverInteraction.Enter -> state = state.copy(hovered = true)
|
||||
is HoverInteraction.Exit -> state = state.copy(hovered = false)
|
||||
is FocusInteraction.Focus -> state = state.copy(focused = true)
|
||||
is FocusInteraction.Unfocus -> state = state.copy(focused = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val thumbSize = style.metrics.thumbSize
|
||||
Spacer(
|
||||
modifier
|
||||
.size(thumbSize)
|
||||
.hoverable(interactionSource, enabled)
|
||||
.background(style.colors.thumbFillFor(state).value, style.thumbShape)
|
||||
.border(
|
||||
alignment = Stroke.Alignment.Outside,
|
||||
width = style.metrics.thumbBorderWidth,
|
||||
color = style.colors.thumbBorderFor(state).value,
|
||||
shape = style.thumbShape,
|
||||
)
|
||||
.focusOutline(state, style.thumbShape),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun snapValueToTick(
|
||||
current: Float,
|
||||
tickFractions: List<Float>,
|
||||
minPx: Float,
|
||||
maxPx: Float,
|
||||
): Float =
|
||||
// target is a closest anchor to the `current`, if exists
|
||||
tickFractions
|
||||
.minByOrNull { abs(lerp(minPx, maxPx, it) - current) }
|
||||
?.run { lerp(minPx, maxPx, this) }
|
||||
?: current
|
||||
|
||||
private fun stepsToTickFractions(steps: Int): List<Float> =
|
||||
if (steps == 0) emptyList() else List(steps + 2) { it.toFloat() / (steps + 1) }
|
||||
|
||||
// Scale x1 from a1..b1 range to a2..b2 range
|
||||
private fun scale(a1: Float, b1: Float, x1: Float, a2: Float, b2: Float) =
|
||||
lerp(a2, b2, calcFraction(a1, b1, x1))
|
||||
|
||||
// Calculate the 0..1 fraction that `pos` value represents between `a` and `b`
|
||||
private fun calcFraction(a: Float, b: Float, pos: Float) =
|
||||
(if (b - a == 0f) 0f else (pos - a) / (b - a)).coerceIn(0f, 1f)
|
||||
|
||||
@Composable
|
||||
private fun CorrectValueSideEffect(
|
||||
scaleToOffset: (Float) -> Float,
|
||||
valueRange: ClosedFloatingPointRange<Float>,
|
||||
trackRange: ClosedFloatingPointRange<Float>,
|
||||
valueState: MutableState<Float>,
|
||||
value: Float,
|
||||
) {
|
||||
SideEffect {
|
||||
val error = (valueRange.endInclusive - valueRange.start) / 1000
|
||||
val newOffset = scaleToOffset(value)
|
||||
if (abs(newOffset - valueState.value) > error && valueState.value in trackRange) {
|
||||
valueState.value = newOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Modifier.sliderSemantics(
|
||||
value: Float,
|
||||
enabled: Boolean,
|
||||
onValueChange: (Float) -> Unit,
|
||||
onValueChangeFinished: (() -> Unit)? = null,
|
||||
valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
|
||||
steps: Int = 0,
|
||||
): Modifier {
|
||||
val coerced = value.coerceIn(valueRange.start, valueRange.endInclusive)
|
||||
|
||||
return semantics {
|
||||
if (!enabled) disabled()
|
||||
|
||||
setProgress(
|
||||
action = { targetValue ->
|
||||
var newValue = targetValue.coerceIn(valueRange.start, valueRange.endInclusive)
|
||||
val originalVal = newValue
|
||||
val resolvedValue = if (steps > 0) {
|
||||
var distance: Float = newValue
|
||||
for (i in 0..steps + 1) {
|
||||
val stepValue = lerp(
|
||||
valueRange.start,
|
||||
valueRange.endInclusive,
|
||||
i.toFloat() / (steps + 1),
|
||||
)
|
||||
if (abs(stepValue - originalVal) <= distance) {
|
||||
distance = abs(stepValue - originalVal)
|
||||
newValue = stepValue
|
||||
}
|
||||
}
|
||||
newValue
|
||||
} else {
|
||||
newValue
|
||||
}
|
||||
// This is to keep it consistent with AbsSeekbar.java: return false if no
|
||||
// change from current.
|
||||
if (resolvedValue == coerced) {
|
||||
false
|
||||
} else {
|
||||
onValueChange(resolvedValue)
|
||||
onValueChangeFinished?.invoke()
|
||||
true
|
||||
}
|
||||
},
|
||||
)
|
||||
}.progressSemantics(value, valueRange, steps)
|
||||
}
|
||||
|
||||
private fun Modifier.sliderTapModifier(
|
||||
draggableState: DraggableState,
|
||||
interactionSource: MutableInteractionSource,
|
||||
maxPx: Float,
|
||||
isRtl: Boolean,
|
||||
rawOffset: State<Float>,
|
||||
gestureEndAction: State<(Float) -> Unit>,
|
||||
pressOffset: MutableState<Float>,
|
||||
enabled: Boolean,
|
||||
) = composed(
|
||||
factory = {
|
||||
if (enabled) {
|
||||
val scope = rememberCoroutineScope()
|
||||
pointerInput(draggableState, interactionSource, maxPx, isRtl) {
|
||||
detectTapGestures(
|
||||
onPress = { pos ->
|
||||
val to = if (isRtl) maxPx - pos.x else pos.x
|
||||
pressOffset.value = to - rawOffset.value
|
||||
try {
|
||||
awaitRelease()
|
||||
} catch (_: GestureCancellationException) {
|
||||
pressOffset.value = 0f
|
||||
}
|
||||
},
|
||||
onTap = {
|
||||
scope.launch {
|
||||
draggableState.drag(MutatePriority.UserInput) {
|
||||
// just trigger animation, press offset will be applied
|
||||
dragBy(0f)
|
||||
}
|
||||
gestureEndAction.value.invoke(0f)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
},
|
||||
inspectorInfo = debugInspectorInfo {
|
||||
name = "sliderTapModifier"
|
||||
properties["draggableState"] = draggableState
|
||||
properties["interactionSource"] = interactionSource
|
||||
properties["maxPx"] = maxPx
|
||||
properties["isRtl"] = isRtl
|
||||
properties["rawOffset"] = rawOffset
|
||||
properties["gestureEndAction"] = gestureEndAction
|
||||
properties["pressOffset"] = pressOffset
|
||||
properties["enabled"] = enabled
|
||||
},
|
||||
)
|
||||
|
||||
private val SliderToTickAnimation = TweenSpec<Float>(durationMillis = 100)
|
||||
|
||||
private suspend fun animateToTarget(
|
||||
draggableState: DraggableState,
|
||||
current: Float,
|
||||
target: Float,
|
||||
velocity: Float,
|
||||
) {
|
||||
draggableState.drag {
|
||||
var latestValue = current
|
||||
Animatable(initialValue = current).animateTo(target, SliderToTickAnimation, velocity) {
|
||||
dragBy(this.value - latestValue)
|
||||
latestValue = this.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Edge case - losing focus on slider while key is pressed will end up with onValueChangeFinished not being invoked
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
private fun Modifier.slideOnKeyEvents(
|
||||
enabled: Boolean,
|
||||
steps: Int,
|
||||
valueRange: ClosedFloatingPointRange<Float>,
|
||||
value: Float,
|
||||
isRtl: Boolean,
|
||||
onValueChangeState: State<(Float) -> Unit>,
|
||||
onValueChangeFinishedState: State<(() -> Unit)?>,
|
||||
): Modifier {
|
||||
require(steps >= 0) { "steps should be >= 0" }
|
||||
|
||||
return this.onKeyEvent {
|
||||
if (!enabled) return@onKeyEvent false
|
||||
|
||||
when (it.type) {
|
||||
KeyEventType.KeyDown -> {
|
||||
val rangeLength = abs(valueRange.endInclusive - valueRange.start)
|
||||
// When steps == 0, it means that a user is not limited by a step length (delta) when using touch or mouse.
|
||||
// But it is not possible to adjust the value continuously when using keyboard buttons -
|
||||
// the delta has to be discrete. In this case, 1% of the valueRange seems to make sense.
|
||||
val actualSteps = if (steps > 0) steps + 1 else 100
|
||||
val delta = rangeLength / actualSteps
|
||||
when {
|
||||
it.isDirectionUp -> {
|
||||
onValueChangeState.value((value + delta).coerceIn(valueRange))
|
||||
true
|
||||
}
|
||||
|
||||
it.isDirectionDown -> {
|
||||
onValueChangeState.value((value - delta).coerceIn(valueRange))
|
||||
true
|
||||
}
|
||||
|
||||
it.isDirectionRight -> {
|
||||
val sign = if (isRtl) -1 else 1
|
||||
onValueChangeState.value((value + sign * delta).coerceIn(valueRange))
|
||||
true
|
||||
}
|
||||
|
||||
it.isDirectionLeft -> {
|
||||
val sign = if (isRtl) -1 else 1
|
||||
onValueChangeState.value((value - sign * delta).coerceIn(valueRange))
|
||||
true
|
||||
}
|
||||
|
||||
it.isHome -> {
|
||||
onValueChangeState.value(valueRange.start)
|
||||
true
|
||||
}
|
||||
|
||||
it.isMoveEnd -> {
|
||||
onValueChangeState.value(valueRange.endInclusive)
|
||||
true
|
||||
}
|
||||
|
||||
it.isPgUp -> {
|
||||
val page = (actualSteps / 10).coerceIn(1, 10)
|
||||
onValueChangeState.value((value - page * delta).coerceIn(valueRange))
|
||||
true
|
||||
}
|
||||
|
||||
it.isPgDn -> {
|
||||
val page = (actualSteps / 10).coerceIn(1, 10)
|
||||
onValueChangeState.value((value + page * delta).coerceIn(valueRange))
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
KeyEventType.KeyUp -> {
|
||||
@Suppress("ComplexCondition") // In original m2 code
|
||||
if (it.isDirectionDown || it.isDirectionUp || it.isDirectionRight ||
|
||||
it.isDirectionLeft || it.isHome || it.isMoveEnd || it.isPgUp || it.isPgDn
|
||||
) {
|
||||
onValueChangeFinishedState.value?.invoke()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal val KeyEvent.isDirectionUp: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_UP
|
||||
|
||||
internal val KeyEvent.isDirectionDown: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_DOWN
|
||||
|
||||
internal val KeyEvent.isDirectionRight: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_RIGHT
|
||||
|
||||
internal val KeyEvent.isDirectionLeft: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_LEFT
|
||||
|
||||
internal val KeyEvent.isHome: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_HOME
|
||||
|
||||
internal val KeyEvent.isMoveEnd: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_END
|
||||
|
||||
internal val KeyEvent.isPgUp: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_PAGE_UP
|
||||
|
||||
internal val KeyEvent.isPgDn: Boolean
|
||||
get() = key.nativeKeyCode == java.awt.event.KeyEvent.VK_PAGE_DOWN
|
||||
|
||||
internal fun lerp(start: Float, stop: Float, fraction: Float): Float =
|
||||
(1 - fraction) * start + fraction * stop
|
||||
|
||||
@Immutable
|
||||
@JvmInline
|
||||
public value class SliderState(public val state: ULong) : FocusableComponentState {
|
||||
|
||||
override val isActive: Boolean
|
||||
get() = state and Active != 0UL
|
||||
|
||||
override val isEnabled: Boolean
|
||||
get() = state and Enabled != 0UL
|
||||
|
||||
override val isFocused: Boolean
|
||||
get() = state and Focused != 0UL
|
||||
|
||||
override val isHovered: Boolean
|
||||
get() = state and Hovered != 0UL
|
||||
|
||||
override val isPressed: Boolean
|
||||
get() = state and Pressed != 0UL
|
||||
|
||||
public fun copy(
|
||||
enabled: Boolean = isEnabled,
|
||||
focused: Boolean = isFocused,
|
||||
pressed: Boolean = isPressed,
|
||||
hovered: Boolean = isHovered,
|
||||
active: Boolean = isActive,
|
||||
): SliderState =
|
||||
of(
|
||||
enabled = enabled,
|
||||
focused = focused,
|
||||
pressed = pressed,
|
||||
hovered = hovered,
|
||||
active = active,
|
||||
)
|
||||
|
||||
override fun toString(): String =
|
||||
"${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " +
|
||||
"isPressed=$isPressed, isActive=$isActive)"
|
||||
|
||||
public companion object {
|
||||
|
||||
public fun of(
|
||||
enabled: Boolean = true,
|
||||
focused: Boolean = false,
|
||||
pressed: Boolean = false,
|
||||
hovered: Boolean = false,
|
||||
active: Boolean = true,
|
||||
): SliderState =
|
||||
SliderState(
|
||||
(if (enabled) Enabled else 0UL) or
|
||||
(if (focused) Focused else 0UL) or
|
||||
(if (hovered) Hovered else 0UL) or
|
||||
(if (pressed) Pressed else 0UL) or
|
||||
(if (active) Active else 0UL),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class SliderDraggableState(
|
||||
val onDelta: (Float) -> Unit,
|
||||
) : DraggableState {
|
||||
|
||||
var isDragging by mutableStateOf(false)
|
||||
private set
|
||||
|
||||
private val dragScope: DragScope = object : DragScope {
|
||||
override fun dragBy(pixels: Float) {
|
||||
onDelta(pixels)
|
||||
}
|
||||
}
|
||||
|
||||
private val scrollMutex = MutatorMutex()
|
||||
|
||||
override suspend fun drag(
|
||||
dragPriority: MutatePriority,
|
||||
block: suspend DragScope.() -> Unit,
|
||||
) {
|
||||
coroutineScope {
|
||||
isDragging = true
|
||||
scrollMutex.mutateWith(dragScope, dragPriority, block)
|
||||
isDragging = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun dispatchRawDelta(delta: Float) {
|
||||
onDelta(delta)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package org.jetbrains.jewel.ui.component.styling
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.ProvidableCompositionLocal
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import org.jetbrains.jewel.foundation.GenerateDataFunctions
|
||||
import org.jetbrains.jewel.foundation.theme.JewelTheme
|
||||
import org.jetbrains.jewel.ui.component.SliderState
|
||||
|
||||
@Stable
|
||||
@GenerateDataFunctions
|
||||
public class SliderStyle(
|
||||
public val colors: SliderColors,
|
||||
public val metrics: SliderMetrics,
|
||||
public val thumbShape: Shape,
|
||||
) {
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@GenerateDataFunctions
|
||||
public class SliderColors(
|
||||
public val track: Color,
|
||||
public val trackFilled: Color,
|
||||
public val trackDisabled: Color,
|
||||
public val trackFilledDisabled: Color,
|
||||
public val stepMarker: Color,
|
||||
public val thumbFill: Color,
|
||||
public val thumbFillDisabled: Color,
|
||||
public val thumbFillFocused: Color,
|
||||
public val thumbFillPressed: Color,
|
||||
public val thumbFillHovered: Color,
|
||||
public val thumbBorder: Color,
|
||||
public val thumbBorderFocused: Color,
|
||||
public val thumbBorderDisabled: Color,
|
||||
public val thumbBorderPressed: Color,
|
||||
public val thumbBorderHovered: Color,
|
||||
) {
|
||||
|
||||
@Composable
|
||||
public fun thumbFillFor(state: SliderState): State<Color> =
|
||||
rememberUpdatedState(
|
||||
state.chooseColor(
|
||||
normal = thumbFill,
|
||||
disabled = thumbFillDisabled,
|
||||
focused = thumbFillFocused,
|
||||
pressed = thumbFillPressed,
|
||||
hovered = thumbFillHovered,
|
||||
),
|
||||
)
|
||||
|
||||
@Composable
|
||||
public fun thumbBorderFor(state: SliderState): State<Color> =
|
||||
rememberUpdatedState(
|
||||
state.chooseColor(
|
||||
normal = thumbBorder,
|
||||
disabled = thumbBorderDisabled,
|
||||
focused = thumbBorderFocused,
|
||||
pressed = thumbBorderPressed,
|
||||
hovered = thumbBorderHovered,
|
||||
),
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun SliderState.chooseColor(
|
||||
normal: Color,
|
||||
disabled: Color,
|
||||
pressed: Color,
|
||||
hovered: Color,
|
||||
focused: Color,
|
||||
) =
|
||||
when {
|
||||
!isEnabled -> disabled
|
||||
isFocused -> focused
|
||||
isPressed && !JewelTheme.isSwingCompatMode -> pressed
|
||||
isHovered && !JewelTheme.isSwingCompatMode -> hovered
|
||||
else -> normal
|
||||
}
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@GenerateDataFunctions
|
||||
public class SliderMetrics(
|
||||
public val trackHeight: Dp,
|
||||
public val thumbSize: DpSize,
|
||||
public val thumbBorderWidth: Dp,
|
||||
public val stepLineHeight: Dp,
|
||||
public val stepLineWidth: Dp,
|
||||
public val trackToStepSpacing: Dp,
|
||||
) {
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
||||
public val LocalSliderStyle: ProvidableCompositionLocal<SliderStyle> =
|
||||
staticCompositionLocalOf {
|
||||
error("No default SliderStyle provided. Have you forgotten the theme?")
|
||||
}
|
||||
@@ -40,12 +40,14 @@ import org.jetbrains.jewel.ui.component.styling.LocalMenuStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalOutlinedButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalRadioButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalScrollbarStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalSliderStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalTextAreaStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalTextFieldStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.LocalTooltipStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.MenuStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.RadioButtonStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.ScrollbarStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.SliderStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TabStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TextAreaStyle
|
||||
import org.jetbrains.jewel.ui.component.styling.TextFieldStyle
|
||||
@@ -165,6 +167,11 @@ public val JewelTheme.Companion.iconButtonStyle: IconButtonStyle
|
||||
@ReadOnlyComposable
|
||||
get() = LocalIconButtonStyle.current
|
||||
|
||||
public val JewelTheme.Companion.sliderStyle: SliderStyle
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalSliderStyle.current
|
||||
|
||||
@Composable
|
||||
public fun BaseJewelTheme(
|
||||
theme: ThemeDefinition,
|
||||
|
||||
Reference in New Issue
Block a user