From b63ba89de87d15d18c07a38f6fe0f2d27ed5bfa3 Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Mon, 15 Apr 2024 10:34:17 +0200 Subject: [PATCH] Add theme name to ThemeDefinition and JewelTheme Names are supposed to be unique per each theme. In standalone, they're hardcoded to "IntUI Light" and "IntUI Dark", and in the bridge they match the Swing LaF name. This allows us to fix a bug in Markdown in the bridge where switching between two LaFs with the same isDark value would cause the Markdown text not to recompose appropriately. --- foundation/api/foundation.api | 5 ++++- .../jewel/foundation/theme/JewelTheme.kt | 10 +++++++++ .../jewel/foundation/theme/ThemeDefinition.kt | 1 + .../jewel/bridge/theme/IntUiBridge.kt | 14 ++++++++---- .../intui/standalone/theme/IntUiTheme.kt | 22 +++++++++++++++++-- .../jewel/samples/ideplugin/MarkdownViewer.kt | 7 +++--- .../view/markdown/MarkdownPreview.kt | 2 +- 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/foundation/api/foundation.api b/foundation/api/foundation.api index 9e1343262..739b401c8 100644 --- a/foundation/api/foundation.api +++ b/foundation/api/foundation.api @@ -754,6 +754,7 @@ public final class org/jetbrains/jewel/foundation/theme/JewelTheme$Companion { public final fun getDefaultTextStyle (Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/text/TextStyle; public final fun getGlobalColors (Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/foundation/GlobalColors; public final fun getGlobalMetrics (Landroidx/compose/runtime/Composer;I)Lorg/jetbrains/jewel/foundation/GlobalMetrics; + public final fun getName (Landroidx/compose/runtime/Composer;I)Ljava/lang/String; public final fun getTextStyle (Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/text/TextStyle; public final fun isDark (Landroidx/compose/runtime/Composer;I)Z public final fun isSwingCompatMode (Landroidx/compose/runtime/Composer;I)Z @@ -767,6 +768,7 @@ public final class org/jetbrains/jewel/foundation/theme/JewelThemeKt { public static final fun getLocalContentColor ()Landroidx/compose/runtime/ProvidableCompositionLocal; public static final fun getLocalIconData ()Landroidx/compose/runtime/ProvidableCompositionLocal; public static final fun getLocalTextStyle ()Landroidx/compose/runtime/ProvidableCompositionLocal; + public static final fun getLocalThemeName ()Landroidx/compose/runtime/ProvidableCompositionLocal; } public final class org/jetbrains/jewel/foundation/theme/ThemeColorPalette { @@ -810,7 +812,7 @@ public final class org/jetbrains/jewel/foundation/theme/ThemeColorPalette$Compan public final class org/jetbrains/jewel/foundation/theme/ThemeDefinition { public static final field $stable I - public synthetic fun (ZLorg/jetbrains/jewel/foundation/GlobalColors;Lorg/jetbrains/jewel/foundation/GlobalMetrics;Landroidx/compose/ui/text/TextStyle;JLorg/jetbrains/jewel/foundation/theme/ThemeColorPalette;Lorg/jetbrains/jewel/foundation/theme/ThemeIconData;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Ljava/lang/String;ZLorg/jetbrains/jewel/foundation/GlobalColors;Lorg/jetbrains/jewel/foundation/GlobalMetrics;Landroidx/compose/ui/text/TextStyle;JLorg/jetbrains/jewel/foundation/theme/ThemeColorPalette;Lorg/jetbrains/jewel/foundation/theme/ThemeIconData;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun equals (Ljava/lang/Object;)Z public final fun getColorPalette ()Lorg/jetbrains/jewel/foundation/theme/ThemeColorPalette; public final fun getContentColor-0d7_KjU ()J @@ -818,6 +820,7 @@ public final class org/jetbrains/jewel/foundation/theme/ThemeDefinition { public final fun getGlobalColors ()Lorg/jetbrains/jewel/foundation/GlobalColors; public final fun getGlobalMetrics ()Lorg/jetbrains/jewel/foundation/GlobalMetrics; public final fun getIconData ()Lorg/jetbrains/jewel/foundation/theme/ThemeIconData; + public final fun getName ()Ljava/lang/String; public fun hashCode ()I public final fun isDark ()Z public fun toString ()Ljava/lang/String; diff --git a/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt b/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt index 47d9703b3..6e844e4d5 100644 --- a/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt +++ b/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt @@ -16,6 +16,11 @@ public interface JewelTheme { public companion object { + public val name: String + @Composable + @ReadOnlyComposable + get() = LocalThemeName.current + public val globalColors: GlobalColors @Composable @ReadOnlyComposable @@ -68,6 +73,7 @@ public fun JewelTheme( @Composable public fun JewelTheme(theme: ThemeDefinition, content: @Composable () -> Unit) { CompositionLocalProvider( + LocalThemeName provides theme.name, LocalIsDarkTheme provides theme.isDark, LocalContentColor provides theme.contentColor, LocalTextStyle provides theme.defaultTextStyle, @@ -77,6 +83,10 @@ public fun JewelTheme(theme: ThemeDefinition, content: @Composable () -> Unit) { ) } +public val LocalThemeName: ProvidableCompositionLocal = staticCompositionLocalOf { + error("No ThemeName provided") +} + public val LocalContentColor: ProvidableCompositionLocal = staticCompositionLocalOf { error("No ContentColor provided. Have you forgotten the theme?") diff --git a/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt b/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt index aded92dc5..21324cd1c 100644 --- a/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt +++ b/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt @@ -10,6 +10,7 @@ import org.jetbrains.jewel.foundation.GlobalMetrics @Immutable @GenerateDataFunctions public class ThemeDefinition( + public val name: String, public val isDark: Boolean, public val globalColors: GlobalColors, public val globalMetrics: GlobalMetrics, diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt index 119849564..e9332739c 100644 --- a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt @@ -134,13 +134,14 @@ internal fun createBridgeThemeDefinition(textStyle: TextStyle): ThemeDefinition logger.debug("Obtaining theme definition from Swing...") return ThemeDefinition( + name = lafName(), isDark = isDark, globalColors = GlobalColors.readFromLaF(), - colorPalette = ThemeColorPalette.readFromLaF(), - iconData = ThemeIconData.readFromLaF(), globalMetrics = GlobalMetrics.readFromLaF(), defaultTextStyle = textStyle, contentColor = JBColor.foreground().toComposeColor(), + colorPalette = ThemeColorPalette.readFromLaF(), + iconData = ThemeIconData.readFromLaF(), ) } @@ -1047,10 +1048,15 @@ private fun readIconButtonStyle(): IconButtonStyle = ), ) -@Suppress("UnstableApiUsage") internal fun isNewUiTheme(): Boolean { if (!NewUI.isEnabled()) return false + val lafName = lafName() + return lafName == "Light" || lafName == "Dark" || lafName == "Light with Light Header" +} + +@Suppress("UnstableApiUsage") +private fun lafName(): String { val lafInfo = LafManager.getInstance().currentUIThemeLookAndFeel - return lafInfo.name == "Light" || lafInfo.name == "Dark" || lafInfo.name == "Light with Light Header" + return lafInfo.name } diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt index eb6c4caa4..765a5c00b 100644 --- a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt @@ -182,7 +182,16 @@ public fun JewelTheme.Companion.lightThemeDefinition( defaultTextStyle: TextStyle = JewelTheme.createDefaultTextStyle(), contentColor: Color = IntUiLightTheme.colors.grey(1), ): ThemeDefinition = - ThemeDefinition(isDark = false, colors, metrics, defaultTextStyle, contentColor, palette, iconData) + ThemeDefinition( + name = "IntUI Light", + isDark = false, + colors, + metrics, + defaultTextStyle, + contentColor, + palette, + iconData, + ) @Composable public fun JewelTheme.Companion.darkThemeDefinition( @@ -193,7 +202,16 @@ public fun JewelTheme.Companion.darkThemeDefinition( defaultTextStyle: TextStyle = JewelTheme.createDefaultTextStyle(), contentColor: Color = IntUiDarkTheme.colors.grey(12), ): ThemeDefinition = - ThemeDefinition(isDark = true, colors, metrics, defaultTextStyle, contentColor, palette, iconData) + ThemeDefinition( + name = "IntUI Dark", + isDark = true, + colors, + metrics, + defaultTextStyle, + contentColor, + palette, + iconData, + ) @Composable public fun ComponentStyling.default(): ComponentStyling = with { diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/MarkdownViewer.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/MarkdownViewer.kt index 9ce862ef3..b2259ed92 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/MarkdownViewer.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/MarkdownViewer.kt @@ -21,16 +21,15 @@ import java.net.URI @Composable internal fun MarkdownPreview(@Language("Markdown") rawMarkdown: String, modifier: Modifier = Modifier) { - val isDark = JewelTheme.isDark - - val markdownStyling = remember(isDark) { MarkdownStyling.create() } + val themeKey = JewelTheme.name + val markdownStyling = remember(themeKey) { MarkdownStyling.create() } val processor = remember { MarkdownProcessor() } // TODO move this away from the composition! val markdownBlocks by remember { derivedStateOf { processor.processMarkdownDocument(rawMarkdown) } } val blockRenderer = - remember(markdownStyling, isDark) { + remember(markdownStyling) { MarkdownBlockRenderer.create( styling = markdownStyling, inlineRenderer = InlineMarkdownRenderer.default(), diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownPreview.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownPreview.kt index f3f6aba6e..cd729d04a 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownPreview.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownPreview.kt @@ -65,7 +65,7 @@ internal fun MarkdownPreview( } val blockRenderer = - remember(markdownStyling, isDark, extensions) { + remember(markdownStyling, extensions) { if (isDark) { MarkdownBlockRenderer.dark( styling = markdownStyling,