From aa8dc74e31c3cee32a9d3f47fd426f6702afae25 Mon Sep 17 00:00:00 2001 From: Davide Magli Date: Thu, 12 Oct 2023 15:33:20 +0200 Subject: [PATCH] iconbutton impl (#164) * wip (cherry picked from commit b51807c216d7c4d7a11797436cdd4bdc8bacabff) * draft (cherry picked from commit ecbaa1ac7c4b33ffb8d01cbdf6c0559ffc6352d0) * lint (cherry picked from commit da55acd356066032e57544eedd544d9877266ca0) * Replace IconButtonMetrics with IconButtonStyle for effective theming The existing metric defining approach, IconButtonMetrics, was restricting the theming of the IconButton component effectively. Thus, the 'IconButtonMetrics' was replaced by 'IconButtonStyle' and the necessary changes for the field change were implemented. This would assist in providing the same theme across different platforms. The 'IconButton' has been made theme-aware by allowing access to theme and style via properties. Changes were made in implementations concerning IntelliJTheme, BaseIntUiTheme, and ComponentShowcaseTab. File names were also appropriately renamed. * Refactor button state logic & tidy method declarations Revised the button state logic of the IconButton component in IconButtonMetrics.kt with a more intuitive 'when' statement, improving readability. Likewise, method declarations in the IntUiBridge.kt file were reformatted for brevity. This maintenance will enhance the code's readability and thus its maintainability. Changes in IconButton.kt reflect the updated logic and background colour application. The @Stable annotation was attached to the IconButtonMetrics interface to indicate thread-safe and side-effect-free operations, a useful indicator for composing efficient composable functions in Jetpack Compose. * Refactor IconButton state selection logic The methodology for selecting the state of the IconButton was refactored from a 'when' statement to the 'chooseValue' * Update button styling in IntUiDarkTheme The IntUiDarkTheme now uses different colors for the "pressed" and "hovered" states of a button. Additionally, the background color selection logic has been refactored in IconButtonMetrics.kt to use a simpler and more readable 'when' construct. * reverted wrong downgrade * happy lint * Change button icon and adjustments on display elements This commit replaces the 'more' button icon with a 'close' button icon in ComponentShowcaseTab.kt. It also removes the 'propagateMinConstraints' property from IconButton.kt. In addition, it adjusts IconButton to not necessarily need 'Modifier.size' in Buttons.kt. These changes are made to improve the UI's look and functionality. * updates improve visibility and user interaction by providing a more intuitive interface. Default background color for disabled buttons has been set * "Add border styling to IconButton This update adds border styling to the IconButton component. The main changes include importing 'border' from the compose foundation, defining border color for different button states, and applying the border in the IconButton component. This change was made to improve the overall visual appearance of the button, especially in different states, providing a more intuitive interface. It also helps better distinguish the buttons from the background, improving user interaction." --------- Co-authored-by: fscarponi --- .../kotlin/org/jetbrains/jewel/IconButton.kt | 82 +++++++++++++ .../jewel/IntelliJComponentStyling.kt | 6 +- .../org/jetbrains/jewel/IntelliJTheme.kt | 6 + .../jewel/styling/IconButtonMetrics.kt | 71 +++++++++++ .../org/jetbrains/jewel/bridge/IntUiBridge.kt | 22 +++- .../jewel/intui/core/BaseIntUiTheme.kt | 2 + .../jewel/intui/standalone/IntUiTheme.kt | 6 + .../styling/IntUiIconButtonStyling.kt | 110 ++++++++++++++++++ .../samples/ideplugin/ComponentShowcaseTab.kt | 9 ++ .../jewel/samples/standalone/Main.kt | 2 +- .../samples/standalone/components/Buttons.kt | 18 ++- 11 files changed, 330 insertions(+), 4 deletions(-) create mode 100644 core/src/main/kotlin/org/jetbrains/jewel/IconButton.kt create mode 100644 core/src/main/kotlin/org/jetbrains/jewel/styling/IconButtonMetrics.kt create mode 100644 int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt diff --git a/core/src/main/kotlin/org/jetbrains/jewel/IconButton.kt b/core/src/main/kotlin/org/jetbrains/jewel/IconButton.kt new file mode 100644 index 000000000..3b6d9a428 --- /dev/null +++ b/core/src/main/kotlin/org/jetbrains/jewel/IconButton.kt @@ -0,0 +1,82 @@ +package org.jetbrains.jewel + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +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.defaultMinSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.semantics.Role +import org.jetbrains.jewel.styling.IconButtonStyle + +@Composable +fun IconButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + style: IconButtonStyle = IntelliJTheme.iconButtonStyle, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + content: @Composable (BoxScope.(ButtonState) -> Unit), +) { + var buttonState by remember(interactionSource) { + mutableStateOf(ButtonState.of(enabled = enabled)) + } + + remember(enabled) { + buttonState = buttonState.copy(enabled = enabled) + } + + LaunchedEffect(interactionSource) { + 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 HoverInteraction.Enter -> buttonState = buttonState.copy(hovered = true) + is HoverInteraction.Exit -> buttonState = buttonState.copy(hovered = false) + + is FocusInteraction.Focus -> buttonState = buttonState.copy(focused = true) + is FocusInteraction.Unfocus -> buttonState = buttonState.copy(focused = false) + } + } + } + val shape = RoundedCornerShape(style.metrics.cornerSize) + val background by style.colors.backgroundFor(buttonState) + val border by style.colors.borderFor(buttonState) + Box( + modifier = modifier + .defaultMinSize(style.metrics.minSize.width, style.metrics.minSize.height) + .clickable( + onClick = onClick, + enabled = enabled, + role = Role.Button, + interactionSource = interactionSource, + indication = NoIndication, + ) + .clip(shape) + .padding(style.metrics.padding) + .background(background) + .border(style.metrics.borderWidth, border), + contentAlignment = Alignment.Center, + content = { + content(buttonState) + }, + ) +} diff --git a/core/src/main/kotlin/org/jetbrains/jewel/IntelliJComponentStyling.kt b/core/src/main/kotlin/org/jetbrains/jewel/IntelliJComponentStyling.kt index 95edef502..53b478cc7 100644 --- a/core/src/main/kotlin/org/jetbrains/jewel/IntelliJComponentStyling.kt +++ b/core/src/main/kotlin/org/jetbrains/jewel/IntelliJComponentStyling.kt @@ -9,6 +9,7 @@ import org.jetbrains.jewel.styling.DividerStyle import org.jetbrains.jewel.styling.DropdownStyle import org.jetbrains.jewel.styling.GroupHeaderStyle import org.jetbrains.jewel.styling.HorizontalProgressBarStyle +import org.jetbrains.jewel.styling.IconButtonStyle import org.jetbrains.jewel.styling.LabelledTextFieldStyle import org.jetbrains.jewel.styling.LazyTreeStyle import org.jetbrains.jewel.styling.LinkStyle @@ -42,6 +43,7 @@ class IntelliJComponentStyling( val textFieldStyle: TextFieldStyle, val circularProgressStyle: CircularProgressStyle, val tooltipStyle: TooltipStyle, + val iconButtonStyle: IconButtonStyle, ) { override fun equals(other: Any?): Boolean { @@ -70,6 +72,7 @@ class IntelliJComponentStyling( if (textFieldStyle != other.textFieldStyle) return false if (circularProgressStyle != other.circularProgressStyle) return false if (tooltipStyle != other.tooltipStyle) return false + if (iconButtonStyle != other.iconButtonStyle) return false return true } @@ -95,6 +98,7 @@ class IntelliJComponentStyling( result = 31 * result + textFieldStyle.hashCode() result = 31 * result + circularProgressStyle.hashCode() result = 31 * result + tooltipStyle.hashCode() + result = 31 * result + iconButtonStyle.hashCode() return result } @@ -106,5 +110,5 @@ class IntelliJComponentStyling( "labelledTextFieldStyle=$labelledTextFieldStyle, lazyTreeStyle=$lazyTreeStyle, linkStyle=$linkStyle, " + "menuStyle=$menuStyle, outlinedButtonStyle=$outlinedButtonStyle, radioButtonStyle=$radioButtonStyle, " + "scrollbarStyle=$scrollbarStyle, textAreaStyle=$textAreaStyle, textFieldStyle=$textFieldStyle, " + - "circularProgressStyle=$circularProgressStyle, tooltipStyle=$tooltipStyle)" + "circularProgressStyle=$circularProgressStyle, tooltipStyle=$tooltipStyle, iconButtonStyle=$iconButtonStyle)" } diff --git a/core/src/main/kotlin/org/jetbrains/jewel/IntelliJTheme.kt b/core/src/main/kotlin/org/jetbrains/jewel/IntelliJTheme.kt index 0b7bf49d2..9b5472886 100644 --- a/core/src/main/kotlin/org/jetbrains/jewel/IntelliJTheme.kt +++ b/core/src/main/kotlin/org/jetbrains/jewel/IntelliJTheme.kt @@ -14,6 +14,7 @@ import org.jetbrains.jewel.styling.DividerStyle import org.jetbrains.jewel.styling.DropdownStyle import org.jetbrains.jewel.styling.GroupHeaderStyle import org.jetbrains.jewel.styling.HorizontalProgressBarStyle +import org.jetbrains.jewel.styling.IconButtonStyle import org.jetbrains.jewel.styling.LabelledTextFieldStyle import org.jetbrains.jewel.styling.LazyTreeStyle import org.jetbrains.jewel.styling.LinkStyle @@ -27,6 +28,7 @@ import org.jetbrains.jewel.styling.LocalDropdownStyle import org.jetbrains.jewel.styling.LocalEditorTabStyle import org.jetbrains.jewel.styling.LocalGroupHeaderStyle import org.jetbrains.jewel.styling.LocalHorizontalProgressBarStyle +import org.jetbrains.jewel.styling.LocalIconButtonStyle import org.jetbrains.jewel.styling.LocalLabelledTextFieldStyle import org.jetbrains.jewel.styling.LocalLazyTreeStyle import org.jetbrains.jewel.styling.LocalLinkStyle @@ -196,6 +198,10 @@ interface IntelliJTheme { @Composable @ReadOnlyComposable get() = LocalTooltipStyle.current + val iconButtonStyle: IconButtonStyle + @Composable + @ReadOnlyComposable + get() = LocalIconButtonStyle.current } } diff --git a/core/src/main/kotlin/org/jetbrains/jewel/styling/IconButtonMetrics.kt b/core/src/main/kotlin/org/jetbrains/jewel/styling/IconButtonMetrics.kt new file mode 100644 index 000000000..04541a1b1 --- /dev/null +++ b/core/src/main/kotlin/org/jetbrains/jewel/styling/IconButtonMetrics.kt @@ -0,0 +1,71 @@ +package org.jetbrains.jewel.styling + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.CornerSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpSize +import org.jetbrains.jewel.ButtonState + +@Stable +interface IconButtonStyle { + + val colors: IconButtonColors + val metrics: IconButtonMetrics +} + +@Immutable +interface IconButtonColors { + + val background: Color + val backgroundDisabled: Color + val backgroundFocused: Color + val backgroundPressed: Color + val backgroundHovered: Color + + val border: Color + val borderDisabled: Color + val borderFocused: Color + val borderPressed: Color + val borderHovered: Color + + @Composable + fun backgroundFor(state: ButtonState) = rememberUpdatedState( + when { + !state.isEnabled -> backgroundDisabled + state.isPressed -> backgroundPressed + state.isHovered -> backgroundHovered + state.isFocused -> backgroundFocused + else -> background + }, + ) + + @Composable + fun borderFor(state: ButtonState) = rememberUpdatedState( + when { + !state.isEnabled -> borderDisabled + state.isPressed -> borderPressed + state.isHovered -> borderHovered + state.isFocused -> borderFocused + else -> border + }, + ) +} + +@Stable +interface IconButtonMetrics { + + val cornerSize: CornerSize + val borderWidth: Dp + val padding: PaddingValues + val minSize: DpSize +} + +val LocalIconButtonStyle = staticCompositionLocalOf { + error("No IconButtonStyle provided") +} diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/IntUiBridge.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/IntUiBridge.kt index 8321102a5..f79e1f3c6 100644 --- a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/IntUiBridge.kt +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/IntUiBridge.kt @@ -50,6 +50,9 @@ import org.jetbrains.jewel.intui.standalone.styling.IntUiGroupHeaderStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiHorizontalProgressBarColors import org.jetbrains.jewel.intui.standalone.styling.IntUiHorizontalProgressBarMetrics import org.jetbrains.jewel.intui.standalone.styling.IntUiHorizontalProgressBarStyle +import org.jetbrains.jewel.intui.standalone.styling.IntUiIconButtonColors +import org.jetbrains.jewel.intui.standalone.styling.IntUiIconButtonMetrics +import org.jetbrains.jewel.intui.standalone.styling.IntUiIconButtonStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiLabelledTextFieldColors import org.jetbrains.jewel.intui.standalone.styling.IntUiLabelledTextFieldMetrics import org.jetbrains.jewel.intui.standalone.styling.IntUiLabelledTextFieldStyle @@ -172,6 +175,7 @@ internal fun createSwingIntUiComponentStyling( circularProgressStyle = readCircularProgressStyle(theme.isDark), tooltipStyle = readTooltipStyle(), textFieldStyle = textFieldStyle, + iconButtonStyle = readIconButtonStyle(), ) } @@ -915,7 +919,23 @@ private fun readTooltipStyle(): IntUiTooltipStyle { content = retrieveColorOrUnspecified("ToolTip.foreground"), background = retrieveColorOrUnspecified("ToolTip.background"), border = retrieveColorOrUnspecified("ToolTip.borderColor"), - shadow = Color.Black.copy(alpha = .6f), + shadow = retrieveColorOrUnspecified("Notification.Shadow.bottom1Color"), ), ) } + +private fun readIconButtonStyle(): IntUiIconButtonStyle = IntUiIconButtonStyle( + metrics = IntUiIconButtonMetrics(CornerSize(DarculaUIUtil.BUTTON_ARC.dp / 2)), + colors = IntUiIconButtonColors( + background = Color.Unspecified, + backgroundDisabled = Color.Unspecified, + backgroundFocused = Color.Unspecified, + backgroundPressed = retrieveColorOrUnspecified("ActionButton.pressedBackground"), + backgroundHovered = retrieveColorOrUnspecified("ActionButton.hoverBackground"), + border = Color.Unspecified, + borderDisabled = Color.Unspecified, + borderFocused = retrieveColorOrUnspecified("ActionButton.focusedBorderColor"), + borderPressed = retrieveColorOrUnspecified("ActionButton.pressedBorderColor"), + borderHovered = retrieveColorOrUnspecified("ActionButton.hoverBorderColor"), + ), +) diff --git a/int-ui/int-ui-core/src/main/kotlin/org/jetbrains/jewel/intui/core/BaseIntUiTheme.kt b/int-ui/int-ui-core/src/main/kotlin/org/jetbrains/jewel/intui/core/BaseIntUiTheme.kt index 814dfbb2a..01464dec5 100644 --- a/int-ui/int-ui-core/src/main/kotlin/org/jetbrains/jewel/intui/core/BaseIntUiTheme.kt +++ b/int-ui/int-ui-core/src/main/kotlin/org/jetbrains/jewel/intui/core/BaseIntUiTheme.kt @@ -37,6 +37,7 @@ import org.jetbrains.jewel.styling.LocalDropdownStyle import org.jetbrains.jewel.styling.LocalEditorTabStyle import org.jetbrains.jewel.styling.LocalGroupHeaderStyle import org.jetbrains.jewel.styling.LocalHorizontalProgressBarStyle +import org.jetbrains.jewel.styling.LocalIconButtonStyle import org.jetbrains.jewel.styling.LocalLabelledTextFieldStyle import org.jetbrains.jewel.styling.LocalLazyTreeStyle import org.jetbrains.jewel.styling.LocalLinkStyle @@ -233,6 +234,7 @@ fun BaseIntUiTheme( LocalIndication provides NoIndication, LocalCircularProgressStyle provides componentStyling.circularProgressStyle, LocalTooltipStyle provides componentStyling.tooltipStyle, + LocalIconButtonStyle provides componentStyling.iconButtonStyle, ) { IntelliJTheme(theme, swingCompatMode, content) } diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/IntUiTheme.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/IntUiTheme.kt index 1f1795a28..f3d94c5d0 100644 --- a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/IntUiTheme.kt +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/IntUiTheme.kt @@ -40,6 +40,7 @@ import org.jetbrains.jewel.intui.standalone.styling.IntUiDividerStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiDropdownStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiGroupHeaderStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiHorizontalProgressBarStyle +import org.jetbrains.jewel.intui.standalone.styling.IntUiIconButtonStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiLabelledTextFieldStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiLazyTreeStyle import org.jetbrains.jewel.intui.standalone.styling.IntUiLinkStyle @@ -58,6 +59,7 @@ import org.jetbrains.jewel.styling.DividerStyle import org.jetbrains.jewel.styling.DropdownStyle import org.jetbrains.jewel.styling.GroupHeaderStyle import org.jetbrains.jewel.styling.HorizontalProgressBarStyle +import org.jetbrains.jewel.styling.IconButtonStyle import org.jetbrains.jewel.styling.LabelledTextFieldStyle import org.jetbrains.jewel.styling.LazyTreeStyle import org.jetbrains.jewel.styling.LinkStyle @@ -136,6 +138,7 @@ object IntUiTheme : BaseIntUiTheme { editorTabStyle: TabStyle = IntUiTabStyle.Editor.dark(svgLoader), circularProgressStyle: CircularProgressStyle = IntUiCircularProgressStyle.dark(), tooltipStyle: IntUiTooltipStyle = IntUiTooltipStyle.dark(), + iconButtonStyle: IconButtonStyle = IntUiIconButtonStyle.dark(), ) = IntelliJComponentStyling( checkboxStyle = checkboxStyle, @@ -158,6 +161,7 @@ object IntUiTheme : BaseIntUiTheme { textFieldStyle = textFieldStyle, circularProgressStyle = circularProgressStyle, tooltipStyle = tooltipStyle, + iconButtonStyle = iconButtonStyle, ) @Composable @@ -183,6 +187,7 @@ object IntUiTheme : BaseIntUiTheme { editorTabStyle: TabStyle = IntUiTabStyle.Editor.light(svgLoader), circularProgressStyle: CircularProgressStyle = IntUiCircularProgressStyle.light(), tooltipStyle: IntUiTooltipStyle = IntUiTooltipStyle.light(), + iconButtonStyle: IconButtonStyle = IntUiIconButtonStyle.light(), ) = IntelliJComponentStyling( checkboxStyle = checkboxStyle, chipStyle = chipStyle, @@ -204,6 +209,7 @@ object IntUiTheme : BaseIntUiTheme { textFieldStyle = textFieldStyle, circularProgressStyle = circularProgressStyle, tooltipStyle = tooltipStyle, + iconButtonStyle = iconButtonStyle, ) } diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt new file mode 100644 index 000000000..4d212b117 --- /dev/null +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt @@ -0,0 +1,110 @@ +package org.jetbrains.jewel.intui.standalone.styling + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.CornerSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.compose.ui.graphics.Color +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.styling.IconButtonColors +import org.jetbrains.jewel.styling.IconButtonMetrics +import org.jetbrains.jewel.styling.IconButtonStyle + +@Stable +data class IntUiIconButtonStyle( + override val colors: IntUiIconButtonColors, + override val metrics: IntUiIconButtonMetrics, +) : IconButtonStyle { + + companion object { + + @Composable + fun light() = IntUiIconButtonStyle(IntUiIconButtonColors.light(), IntUiIconButtonMetrics()) + + @Composable + fun dark() = IntUiIconButtonStyle(IntUiIconButtonColors.dark(), IntUiIconButtonMetrics()) + } +} + +@Immutable +data class IntUiIconButtonColors( + override val background: Color, + override val backgroundDisabled: Color, + override val backgroundFocused: Color, + override val backgroundPressed: Color, + override val backgroundHovered: Color, + override val border: Color, + override val borderDisabled: Color, + override val borderFocused: Color, + override val borderPressed: Color, + override val borderHovered: Color, +) : IconButtonColors { + + companion object { + + @Composable + fun light( + background: Color = Color.Unspecified, + backgroundDisabled: Color = background, + backgroundFocused: Color = background, + backgroundPressed: Color = IntUiLightTheme.colors.grey(11), + backgroundHovered: Color = IntUiLightTheme.colors.grey(12), + border: Color = background, + borderDisabled: Color = border, + borderFocused: Color = IntUiLightTheme.colors.blue(5), + borderPressed: Color = backgroundPressed, + borderHovered: Color = backgroundHovered, + ) = + IntUiIconButtonColors( + background, + backgroundDisabled, + backgroundFocused, + backgroundPressed, + backgroundHovered, + border, + borderDisabled, + borderFocused, + borderPressed, + borderHovered, + ) + + @Composable + fun dark( + background: Color = Color.Unspecified, + backgroundDisabled: Color = background, + backgroundFocused: Color = background, + backgroundPressed: Color = IntUiDarkTheme.colors.grey(5), + backgroundHovered: Color = IntUiDarkTheme.colors.grey(3), + border: Color = background, + borderDisabled: Color = border, + borderFocused: Color = IntUiDarkTheme.colors.blue(6), + borderPressed: Color = backgroundPressed, + borderHovered: Color = backgroundHovered, + ) = + IntUiIconButtonColors( + background, + backgroundDisabled, + backgroundFocused, + backgroundPressed, + backgroundHovered, + border, + borderDisabled, + borderFocused, + borderPressed, + borderHovered, + ) + } +} + +@Stable +data class IntUiIconButtonMetrics( + override val cornerSize: CornerSize = CornerSize(4.dp), + override val borderWidth: Dp = 1.dp, + override val padding: PaddingValues = PaddingValues(0.dp), + override val minSize: DpSize = DpSize(16.dp, 16.dp), +) : IconButtonMetrics diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt index 823e23b71..41d35cae2 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt @@ -31,6 +31,7 @@ import org.jetbrains.jewel.CircularProgressIndicator import org.jetbrains.jewel.CircularProgressIndicatorBig import org.jetbrains.jewel.DefaultButton import org.jetbrains.jewel.Icon +import org.jetbrains.jewel.IconButton import org.jetbrains.jewel.LazyTree import org.jetbrains.jewel.LocalResourceLoader import org.jetbrains.jewel.OutlinedButton @@ -129,6 +130,14 @@ private fun RowScope.ColumnOne(resourceLoader: ResourceLoader) { Icon(painter = painter, modifier = Modifier.border(1.dp, Color.Magenta), contentDescription = "An icon") } + Row { + IconButton(onClick = { }) { + val painterProvider = retrieveStatelessIcon("actions/close.svg", svgLoader, IntUiTheme.iconData) + val painter by painterProvider.getPainter(resourceLoader) + Icon(painter = painter, contentDescription = "An icon") + } + } + Row { Text("Circular progress small: ") CircularProgressIndicator(svgLoader) diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt index b9785e2da..1ed2fd48b 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt @@ -100,7 +100,7 @@ private fun ComponentShowcase(svgLoader: JewelSvgLoader, resourceLoader: Resourc horizontalAlignment = Alignment.Start, ) { Borders() - Buttons() + Buttons(svgLoader, resourceLoader) Dropdowns() Checkboxes() RadioButtons() diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/components/Buttons.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/components/Buttons.kt index 3096ed884..36277b54c 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/components/Buttons.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/components/Buttons.kt @@ -4,16 +4,23 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.ResourceLoader import androidx.compose.ui.unit.dp import org.jetbrains.jewel.DefaultButton import org.jetbrains.jewel.GroupHeader +import org.jetbrains.jewel.Icon +import org.jetbrains.jewel.IconButton +import org.jetbrains.jewel.JewelSvgLoader import org.jetbrains.jewel.OutlinedButton import org.jetbrains.jewel.Text +import org.jetbrains.jewel.styling.ResourcePainterProvider @Composable -fun Buttons() { +fun Buttons(svgLoader: JewelSvgLoader, resourceLoader: ResourceLoader) { GroupHeader("Buttons") Row( modifier = Modifier.fillMaxWidth(), @@ -35,5 +42,14 @@ fun Buttons() { DefaultButton(onClick = {}, enabled = false) { Text("Default disabled") } + + IconButton(onClick = {}) { + val iconProvider = remember { ResourcePainterProvider.stateless("icons/close.svg", svgLoader) } + val iconPainter by iconProvider.getPainter(resourceLoader) + Icon( + painter = iconPainter, + "icon", + ) + } } }