mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[JEWEL-947] Add Image composable
This adds a new `Image` composable, similar to `Icon` but less prescriptive, while still allowing users to take advantage of Jewel's icon loading pipeline. closes https://github.com/JetBrains/intellij-community/pull/3180 GitOrigin-RevId: 24682400286f468ac8cb4bd31563c6c5b79607f2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b638b1a99a
commit
3e352e3297
+24
@@ -7,7 +7,9 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@@ -21,6 +23,7 @@ import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.jewel.foundation.theme.JewelTheme
|
||||
import org.jetbrains.jewel.samples.showcase.ShowcaseIcons
|
||||
import org.jetbrains.jewel.ui.component.Icon
|
||||
import org.jetbrains.jewel.ui.component.Image
|
||||
import org.jetbrains.jewel.ui.component.Text
|
||||
import org.jetbrains.jewel.ui.icons.AllIconsKeys
|
||||
import org.jetbrains.jewel.ui.painter.badge.DotBadgeShape
|
||||
@@ -96,5 +99,26 @@ public fun Icons(modifier: Modifier = Modifier) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
Text("Images:")
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Image(ShowcaseIcons.jewelLogo, contentDescription = "Jewel Logo", modifier = Modifier.size(96.dp))
|
||||
|
||||
// Note: this currently looks identical to the hint-less image due to JEWEL-971
|
||||
Image(
|
||||
iconKey = ShowcaseIcons.jewelLogo,
|
||||
contentDescription = "Jewel Logo with hint",
|
||||
hints = arrayOf(Stroke(Color.Red)),
|
||||
modifier = Modifier.size(96.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,6 +396,9 @@ f:org.jetbrains.jewel.ui.component.IconKt
|
||||
- sf:Icon-ww6aTOc(androidx.compose.ui.graphics.painter.Painter,java.lang.String,androidx.compose.ui.Modifier,J,androidx.compose.runtime.Composer,I,I):V
|
||||
- sf:Icon-ww6aTOc(androidx.compose.ui.graphics.vector.ImageVector,java.lang.String,androidx.compose.ui.Modifier,J,androidx.compose.runtime.Composer,I,I):V
|
||||
- sf:painterResource(java.lang.String,androidx.compose.runtime.Composer,I):androidx.compose.ui.graphics.painter.Painter
|
||||
f:org.jetbrains.jewel.ui.component.ImageKt
|
||||
- sf:Image(org.jetbrains.jewel.ui.icon.IconKey,java.lang.String,androidx.compose.ui.Modifier,java.lang.Class,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,F,androidx.compose.ui.graphics.ColorFilter,androidx.compose.runtime.Composer,I,I):V
|
||||
- sf:Image(org.jetbrains.jewel.ui.icon.IconKey,java.lang.String,org.jetbrains.jewel.ui.painter.PainterHint[],androidx.compose.ui.Modifier,java.lang.Class,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,F,androidx.compose.ui.graphics.ColorFilter,androidx.compose.runtime.Composer,I,I):V
|
||||
f:org.jetbrains.jewel.ui.component.InfoTextKt
|
||||
- sf:InfoText-F-Jr8PA(androidx.compose.ui.text.AnnotatedString,androidx.compose.ui.Modifier,J,J,androidx.compose.ui.text.font.FontStyle,androidx.compose.ui.text.font.FontWeight,androidx.compose.ui.text.font.FontFamily,J,androidx.compose.ui.text.style.TextDecoration,I,J,I,Z,I,java.util.Map,kotlin.jvm.functions.Function1,androidx.compose.ui.text.TextStyle,androidx.compose.runtime.Composer,I,I,I):V
|
||||
- sf:InfoText-bAzTDeA(java.lang.String,androidx.compose.ui.Modifier,J,J,androidx.compose.ui.text.font.FontStyle,androidx.compose.ui.text.font.FontWeight,androidx.compose.ui.text.font.FontFamily,J,androidx.compose.ui.text.style.TextDecoration,I,J,I,Z,I,kotlin.jvm.functions.Function1,androidx.compose.ui.text.TextStyle,androidx.compose.runtime.Composer,I,I,I):V
|
||||
|
||||
@@ -38,6 +38,18 @@ import org.jetbrains.jewel.ui.icon.newUiChecker
|
||||
import org.jetbrains.jewel.ui.painter.PainterHint
|
||||
import org.jetbrains.jewel.ui.painter.rememberResourcePainterProvider
|
||||
|
||||
/**
|
||||
* Icon component that draws an icon from an [IconKey].
|
||||
*
|
||||
* @param key The [IconKey] to resolve the icon from.
|
||||
* @param contentDescription text used by accessibility services to describe what this icon represents. This should
|
||||
* always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action
|
||||
* that a user can take.
|
||||
* @param modifier optional [Modifier] for this Icon.
|
||||
* @param iconClass The class to use for resolving the icon resource. Defaults to `key.iconClass`.
|
||||
* @param tint tint to be applied to the icon. If [Color.Unspecified] is provided, then no tint is applied.
|
||||
* @param hints [PainterHint]s to be used by the painter.
|
||||
*/
|
||||
@Suppress("ComposableParamOrder") // It doesn't like the vararg
|
||||
@Composable
|
||||
public fun Icon(
|
||||
@@ -56,6 +68,18 @@ public fun Icon(
|
||||
Icon(painter = painter, contentDescription = contentDescription, modifier = modifier, tint = tint)
|
||||
}
|
||||
|
||||
/**
|
||||
* Icon component that draws an icon from an [IconKey] using a [tint].
|
||||
*
|
||||
* @param key The [IconKey] to resolve the icon from.
|
||||
* @param contentDescription text used by accessibility services to describe what this icon represents. This should
|
||||
* always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action
|
||||
* that a user can take.
|
||||
* @param modifier optional [Modifier] for this Icon.
|
||||
* @param iconClass The class to use for resolving the icon resource. Defaults to `key.iconClass`.
|
||||
* @param tint tint to be applied to the icon. If [Color.Unspecified] is provided, then no tint is applied.
|
||||
* @param hint [PainterHint] to be passed to the painter.
|
||||
*/
|
||||
@Suppress("ComposableParamOrder") // To fix in JEWEL-929
|
||||
@Composable
|
||||
public fun Icon(
|
||||
@@ -75,6 +99,18 @@ public fun Icon(
|
||||
Icon(painter = painter, contentDescription = contentDescription, modifier = modifier, tint = tint)
|
||||
}
|
||||
|
||||
/**
|
||||
* Icon component that draws an icon from an [IconKey] using a [colorFilter].
|
||||
*
|
||||
* @param key The [IconKey] to resolve the icon from.
|
||||
* @param contentDescription text used by accessibility services to describe what this icon represents. This should
|
||||
* always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action
|
||||
* that a user can take.
|
||||
* @param modifier optional [Modifier] for this Icon.
|
||||
* @param iconClass The class to use for resolving the icon resource. Defaults to `key.iconClass`.
|
||||
* @param colorFilter [ColorFilter] to be applied to the icon.
|
||||
* @param hint [PainterHint] to be passed to the painter.
|
||||
*/
|
||||
@Suppress("ComposableParamOrder") // To fix in JEWEL-929
|
||||
@Composable
|
||||
public fun Icon(
|
||||
@@ -93,6 +129,18 @@ public fun Icon(
|
||||
Icon(painter = painter, contentDescription = contentDescription, modifier = modifier, colorFilter = colorFilter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Icon component that draws an icon from an [IconKey] using a [colorFilter].
|
||||
*
|
||||
* @param key The [IconKey] to resolve the icon from.
|
||||
* @param contentDescription text used by accessibility services to describe what this icon represents. This should
|
||||
* always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action
|
||||
* that a user can take.
|
||||
* @param modifier optional [Modifier] for this Icon.
|
||||
* @param iconClass The class to use for resolving the icon resource. Defaults to `key.iconClass`.
|
||||
* @param colorFilter [ColorFilter] to be applied to the icon.
|
||||
* @param hints [PainterHint]s to be used by the painter.
|
||||
*/
|
||||
@Suppress("ComposableParamOrder") // To fix in JEWEL-929
|
||||
@Composable
|
||||
public fun Icon(
|
||||
@@ -214,6 +262,10 @@ public fun Icon(
|
||||
)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
"Please use iconKeys with the Icon or Image components instead. " +
|
||||
"This will prevent issues when running in the IntelliJ Platform."
|
||||
)
|
||||
@Composable
|
||||
public fun painterResource(resourcePath: String): Painter =
|
||||
when (resourcePath.substringAfterLast(".").lowercase()) {
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.jewel.ui.component
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
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.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.DefaultAlpha
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import org.jetbrains.jewel.foundation.theme.JewelTheme
|
||||
import org.jetbrains.jewel.ui.icon.IconKey
|
||||
import org.jetbrains.jewel.ui.icon.newUiChecker
|
||||
import org.jetbrains.jewel.ui.painter.PainterHint
|
||||
import org.jetbrains.jewel.ui.painter.rememberResourcePainterProvider
|
||||
|
||||
/**
|
||||
* A Composable that lays out and draws a given [IconKey].
|
||||
*
|
||||
* This component is similar to [Icon], but it does not have a default size, and it exposes more control over the
|
||||
* image's appearance, like [contentScale], [alignment], and [alpha]. This will attempt to size the composable according
|
||||
* to the [IconKey]'s intrinsic size. However, an optional [Modifier] can be provided to adjust the sizing or draw
|
||||
* additional content (e.g., a background).
|
||||
*
|
||||
* @param iconKey The [IconKey] to draw.
|
||||
* @param contentDescription Text used by accessibility services to describe what this image represents. This should
|
||||
* always be provided unless this image is used for decorative purposes, and does not represent a meaningful action
|
||||
* that a user can take. This text should be localized, such as by using `stringResource` or similar.
|
||||
* @param modifier [Modifier] for this image.
|
||||
* @param iconClass The class to use for resolving the icon resource. Defaults to `iconKey.iconClass`.
|
||||
* @param alignment Alignment parameter used to place the [iconKey] in the given bounds.
|
||||
* @param contentScale Scale parameter used to determine the aspect ratio scaling to be used if the bounds are a
|
||||
* different size from the intrinsic size of the [iconKey].
|
||||
* @param alpha Opacity to be applied to the [iconKey] when it is rendered on screen.
|
||||
* @param colorFilter [ColorFilter] to apply for the [iconKey] when it is rendered onscreen.
|
||||
* @see Icon
|
||||
*/
|
||||
@Composable
|
||||
public fun Image(
|
||||
iconKey: IconKey,
|
||||
contentDescription: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
iconClass: Class<*> = iconKey.iconClass,
|
||||
alignment: Alignment = Alignment.Center,
|
||||
contentScale: ContentScale = ContentScale.Fit,
|
||||
alpha: Float = DefaultAlpha,
|
||||
colorFilter: ColorFilter? = null,
|
||||
) {
|
||||
Image(
|
||||
iconKey,
|
||||
contentDescription,
|
||||
hints = emptyArray(),
|
||||
modifier,
|
||||
iconClass,
|
||||
alignment,
|
||||
contentScale,
|
||||
alpha,
|
||||
colorFilter,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A Composable that lays out and draws a given [IconKey].
|
||||
*
|
||||
* This component is similar to [Icon], but it does not have a default size, and it exposes more control over the
|
||||
* image's appearance, like [contentScale], [alignment], and [alpha]. This will attempt to size the composable according
|
||||
* to the [IconKey]'s intrinsic size. However, an optional [Modifier] can be provided to adjust the sizing or draw
|
||||
* additional content (e.g., a background).
|
||||
*
|
||||
* @param iconKey The [IconKey] to draw.
|
||||
* @param contentDescription Text used by accessibility services to describe what this image represents. This should
|
||||
* always be provided unless this image is used for decorative purposes, and does not represent a meaningful action
|
||||
* that a user can take. This text should be localized, such as by using `stringResource` or similar.
|
||||
* @param hints [PainterHint]s to be used by the painter.
|
||||
* @param modifier [Modifier] for this image.
|
||||
* @param iconClass The class to use for resolving the icon resource. Defaults to `iconKey.iconClass`.
|
||||
* @param alignment Alignment parameter used to place the [iconKey] in the given bounds.
|
||||
* @param contentScale Scale parameter used to determine the aspect ratio scaling to be used if the bounds are a
|
||||
* different size from the intrinsic size of the [iconKey].
|
||||
* @param alpha Opacity to be applied to the [iconKey] when it is rendered on screen.
|
||||
* @param colorFilter [ColorFilter] to apply for the [iconKey] when it is rendered onscreen.
|
||||
* @see Icon
|
||||
*/
|
||||
@Composable
|
||||
public fun Image(
|
||||
iconKey: IconKey,
|
||||
contentDescription: String?,
|
||||
vararg hints: PainterHint,
|
||||
modifier: Modifier = Modifier,
|
||||
iconClass: Class<*> = iconKey.iconClass,
|
||||
alignment: Alignment = Alignment.Center,
|
||||
contentScale: ContentScale = ContentScale.Fit,
|
||||
alpha: Float = DefaultAlpha,
|
||||
colorFilter: ColorFilter? = null,
|
||||
) {
|
||||
val isNewUi = JewelTheme.newUiChecker.isNewUi()
|
||||
val path = remember(iconKey, isNewUi) { iconKey.path(isNewUi) }
|
||||
val painterProvider = rememberResourcePainterProvider(path, iconClass)
|
||||
val painter by painterProvider.getPainter(*hints)
|
||||
|
||||
Image(painter, contentDescription, modifier, alignment, contentScale, alpha, colorFilter)
|
||||
}
|
||||
+1
-1
@@ -53,7 +53,7 @@ private fun Element.patchColorAttribute(attrName: String, pattern: Map<Color, Co
|
||||
val alpha = opacity.toFloatOrNull() ?: 1.0f
|
||||
val originalColor = tryParseColor(color, alpha) ?: return
|
||||
val newColor = pattern[originalColor] ?: return
|
||||
setAttribute(attrName, newColor.copy(alpha = 1.0f).toRgbaHexString())
|
||||
setAttribute(attrName, newColor.copy(alpha = 1.0f).toRgbaHexString(omitAlphaWhenFullyOpaque = true))
|
||||
if (newColor.alpha != alpha) {
|
||||
setAttribute("$attrName-opacity", newColor.alpha.toString())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user