From d73420a16ea651aced38a72d742622a796e26ac3 Mon Sep 17 00:00:00 2001 From: Kanro Date: Fri, 3 Nov 2023 22:04:19 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=80=20Fix=20icon=20don't=20be=20scaled?= =?UTF-8?q?=20after=20density=20changed=20(#239)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix icon don't be scaled after density changed * Fix comments --- ide-laf-bridge/api/ide-laf-bridge.api | 6 ++- .../org/jetbrains/jewel/bridge/BridgeUtils.kt | 11 ++--- .../jewel/bridge/JewelComposePanel.kt | 30 +++++++++++++ .../jewel/bridge/SwingBridgeService.kt | 4 -- .../jewel/bridge/ToolWindowExtensions.kt | 23 +++++----- .../jewel/bridge/theme/SwingBridgeTheme.kt | 3 +- .../samples/ideplugin/ComponentShowcaseTab.kt | 30 ++++++------- .../releasessample/ReleasesSampleCompose.kt | 43 +++++++++---------- .../ui/painter/ResourcePainterProvider.kt | 2 +- 9 files changed, 86 insertions(+), 66 deletions(-) create mode 100644 ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelComposePanel.kt diff --git a/ide-laf-bridge/api/ide-laf-bridge.api b/ide-laf-bridge/api/ide-laf-bridge.api index 8df0d285a..548302112 100644 --- a/ide-laf-bridge/api/ide-laf-bridge.api +++ b/ide-laf-bridge/api/ide-laf-bridge.api @@ -44,13 +44,17 @@ public final class org/jetbrains/jewel/bridge/JewelBridgeException$KeysNotFoundE public fun (Ljava/util/List;Ljava/lang/String;)V } +public final class org/jetbrains/jewel/bridge/JewelComposePanelKt { + public static final fun JewelComposePanel (Lkotlin/jvm/functions/Function2;)Ljavax/swing/JComponent; + public static final fun getLocalComponent ()Landroidx/compose/runtime/ProvidableCompositionLocal; +} + public final class org/jetbrains/jewel/bridge/ToolWindowExtensionsKt { public static final fun addComposeTab (Lcom/intellij/openapi/wm/ToolWindow;Ljava/lang/String;ZZLkotlin/jvm/functions/Function3;)V public static synthetic fun addComposeTab$default (Lcom/intellij/openapi/wm/ToolWindow;Ljava/lang/String;ZZLkotlin/jvm/functions/Function3;ILjava/lang/Object;)V } public abstract interface class org/jetbrains/jewel/bridge/ToolWindowScope { - public abstract fun getPanel ()Landroidx/compose/ui/awt/ComposePanel; public abstract fun getToolWindow ()Lcom/intellij/openapi/wm/ToolWindow; } diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeUtils.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeUtils.kt index 1340bd885..4d1bfdd2e 100644 --- a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeUtils.kt +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeUtils.kt @@ -35,7 +35,6 @@ import org.jetbrains.skiko.awt.font.AwtFontManager import org.jetbrains.skiko.toSkikoTypefaceOrNull import java.awt.Dimension import java.awt.Font -import java.awt.GraphicsEnvironment import java.awt.Insets import javax.swing.UIManager @@ -222,13 +221,9 @@ internal operator fun TextUnit.plus(delta: Float): TextUnit = else -> this } -internal fun retrieveDensity(): Density { +internal fun retrieveIdeaDensity(sourceDensity: Density): Density { val ideaScale = UISettingsUtils.getInstance().currentIdeScale - val scale = GraphicsEnvironment.getLocalGraphicsEnvironment() - .defaultScreenDevice - .defaultConfiguration - .defaultTransform - .scaleX * ideaScale + val scale = ideaScale * sourceDensity.density - return Density(scale.toFloat(), 1f) + return Density(scale, sourceDensity.fontScale) } diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelComposePanel.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelComposePanel.kt new file mode 100644 index 000000000..2f1d87c70 --- /dev/null +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelComposePanel.kt @@ -0,0 +1,30 @@ +package org.jetbrains.jewel.bridge + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.ProvidableCompositionLocal +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.awt.ComposePanel +import org.jetbrains.jewel.bridge.actionSystem.ComponentDataProviderBridge +import org.jetbrains.jewel.bridge.theme.SwingBridgeTheme +import org.jetbrains.jewel.foundation.ExperimentalJewelApi +import javax.swing.JComponent + +public fun JewelComposePanel( + content: @Composable () -> Unit, +): JComponent { + return ComposePanel().apply { + setContent { + SwingBridgeTheme { + CompositionLocalProvider(LocalComponent provides this@apply) { + ComponentDataProviderBridge(this@apply, content = content) + } + } + } + } +} + +@ExperimentalJewelApi +public val LocalComponent: ProvidableCompositionLocal = staticCompositionLocalOf { + error("CompositionLocal LocalComponent not provided") +} diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/SwingBridgeService.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/SwingBridgeService.kt index 703e4e9c7..3d25a7719 100644 --- a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/SwingBridgeService.kt +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/SwingBridgeService.kt @@ -1,7 +1,6 @@ package org.jetbrains.jewel.bridge import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.Density import com.intellij.openapi.components.Service import com.intellij.openapi.components.Service.Level import kotlinx.coroutines.CoroutineScope @@ -42,14 +41,12 @@ internal class SwingBridgeService(scope: CoroutineScope) { return BridgeThemeData( themeDefinition = createBridgeThemeDefinition(), componentStyling = createBridgeComponentStyling(themeDefinition), - density = retrieveDensity(), ) } internal data class BridgeThemeData( val themeDefinition: ThemeDefinition, val componentStyling: ComponentStyling, - val density: Density, ) { public companion object { @@ -67,7 +64,6 @@ internal class SwingBridgeService(scope: CoroutineScope) { dropdownTextStyle = TextStyle.Default, linkTextStyle = TextStyle.Default, ), - density = retrieveDensity(), ) } } diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt index d3fa7d91a..1292895c0 100644 --- a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt @@ -1,7 +1,6 @@ package org.jetbrains.jewel.bridge import androidx.compose.runtime.Composable -import androidx.compose.ui.awt.ComposePanel import com.intellij.openapi.wm.ToolWindow import org.jetbrains.jewel.foundation.enableNewSwingCompositing @@ -15,15 +14,17 @@ public fun ToolWindow.addComposeTab( // The operation is idempotent, so we can safely do it every time. enableNewSwingCompositing() - val composePanel = ComposePanel() - - val scope = object : ToolWindowScope { - override val toolWindow: ToolWindow = this@addComposeTab - override val panel: ComposePanel = composePanel - } - - composePanel.setContent { scope.content() } - val tabContent = contentManager.factory.createContent(composePanel, tabDisplayName, isLockable) + val tabContent = contentManager.factory.createContent( + JewelComposePanel { + val scope = object : ToolWindowScope { + override val toolWindow: ToolWindow + get() = this@addComposeTab + } + scope.content() + }, + tabDisplayName, + isLockable, + ) tabContent.isCloseable = isCloseable contentManager.addContent(tabContent) } @@ -31,6 +32,4 @@ public fun ToolWindow.addComposeTab( public interface ToolWindowScope { public val toolWindow: ToolWindow - - public val panel: ComposePanel } diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt index 5c541b110..2a17ca407 100644 --- a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt @@ -8,6 +8,7 @@ import androidx.compose.ui.platform.LocalDensity import com.intellij.openapi.components.service import org.jetbrains.jewel.bridge.BridgePainterHintsProvider import org.jetbrains.jewel.bridge.SwingBridgeService +import org.jetbrains.jewel.bridge.retrieveIdeaDensity import org.jetbrains.jewel.foundation.ExperimentalJewelApi import org.jetbrains.jewel.ui.ComponentStyling import org.jetbrains.jewel.ui.painter.LocalPainterHintsProvider @@ -28,7 +29,7 @@ public fun SwingBridgeTheme(content: @Composable () -> Unit) { ) { CompositionLocalProvider( LocalPainterHintsProvider provides BridgePainterHintsProvider(themeData.themeDefinition.isDark), - LocalDensity provides themeData.density, + LocalDensity provides retrieveIdeaDensity(LocalDensity.current), ) { content() } 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 65c02566f..0d4ebefa4 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 @@ -26,8 +26,8 @@ import androidx.compose.ui.unit.dp 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.theme.SwingBridgeTheme import org.jetbrains.jewel.bridge.toComposeColor import org.jetbrains.jewel.foundation.lazy.tree.buildTree import org.jetbrains.jewel.foundation.modifier.onActivated @@ -49,21 +49,19 @@ import org.jetbrains.jewel.ui.component.Tooltip @Composable internal fun ToolWindowScope.ComponentShowcaseTab() { - SwingBridgeTheme { - val bgColor by remember(JewelTheme.isDark) { mutableStateOf(JBColor.PanelBackground.toComposeColor()) } - - val scrollState = rememberScrollState() - Row( - modifier = Modifier.trackComponentActivation(panel) - .fillMaxSize() - .background(bgColor) - .verticalScroll(scrollState) - .padding(16.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), - ) { - ColumnOne() - ColumnTwo() - } + val bgColor by remember(JewelTheme.isDark) { mutableStateOf(JBColor.PanelBackground.toComposeColor()) } + + val scrollState = rememberScrollState() + Row( + modifier = Modifier.trackComponentActivation(LocalComponent.current) + .fillMaxSize() + .background(bgColor) + .verticalScroll(scrollState) + .padding(16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + ) { + ColumnOne() + ColumnTwo() } } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt index 1593cbc28..e6b40966e 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt @@ -74,7 +74,6 @@ import kotlinx.coroutines.runBlocking import kotlinx.datetime.toJavaLocalDate import org.jetbrains.jewel.bridge.retrieveColorOrUnspecified import org.jetbrains.jewel.bridge.retrieveTextStyle -import org.jetbrains.jewel.bridge.theme.SwingBridgeTheme import org.jetbrains.jewel.bridge.toComposeColor import org.jetbrains.jewel.bridge.toFontFamily import org.jetbrains.jewel.foundation.lazy.SelectableLazyColumn @@ -103,28 +102,26 @@ import kotlin.time.Duration.Companion.seconds @OptIn(DependsOnJBR::class) @Composable fun ReleasesSampleCompose(project: Project) { - SwingBridgeTheme { - var selectedItem: ContentItem? by remember { mutableStateOf(null) } - HorizontalSplitLayout( - first = { modifier -> - LeftColumn( - project = project, - modifier = modifier.fillMaxSize(), - onSelectedItemChange = { selectedItem = it }, - ) - }, - second = { modifier -> - RightColumn( - selectedItem = selectedItem, - modifier = modifier.fillMaxSize(), - ) - }, - Modifier.fillMaxSize(), - initialDividerPosition = 400.dp, - minRatio = .15f, - maxRatio = .7f, - ) - } + var selectedItem: ContentItem? by remember { mutableStateOf(null) } + HorizontalSplitLayout( + first = { modifier -> + LeftColumn( + project = project, + modifier = modifier.fillMaxSize(), + onSelectedItemChange = { selectedItem = it }, + ) + }, + second = { modifier -> + RightColumn( + selectedItem = selectedItem, + modifier = modifier.fillMaxSize(), + ) + }, + Modifier.fillMaxSize(), + initialDividerPosition = 400.dp, + minRatio = .15f, + maxRatio = .7f, + ) } @Composable diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt index c11b2a2a1..dc5c68909 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt @@ -84,7 +84,7 @@ public class ResourcePainterProvider( currentHintsProvider.hints(basePath) .forEach { scope.resolveHint(it) } - val cacheKey = scope.acceptedHints.hashCode() + val cacheKey = scope.acceptedHints.hashCode() * 31 + LocalDensity.current.hashCode() if (inDebugMode && cache[cacheKey] != null) { println("Cache hit for $basePath(${scope.acceptedHints.joinToString()})")