diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt index f6fe65fcde..bf8a2a606d 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt @@ -4,6 +4,7 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.project.DumbAware import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.NlsContexts.TabTitle import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowFactory import kotlinx.coroutines.CoroutineScope @@ -14,6 +15,7 @@ import kotlinx.coroutines.cancel import org.jetbrains.jewel.bridge.addComposeTab import org.jetbrains.jewel.samples.ideplugin.releasessample.ReleasesSampleCompose import org.jetbrains.jewel.samples.ideplugin.releasessample.ReleasesSamplePanel +import javax.swing.JComponent @Suppress("unused") @ExperimentalCoroutinesApi @@ -24,21 +26,21 @@ internal class JewelDemoToolWindowFactory : ToolWindowFactory, DumbAware { ComponentShowcaseTab() } - addSwingTab(toolWindow) + toolWindow.addSwingTab( + ReleasesSamplePanel(toolWindow.disposable.createCoroutineScope()), + "Swing Sample", + ) toolWindow.addComposeTab("Compose Sample") { ReleasesSampleCompose(project) } + + toolWindow.addSwingTab(SwingComparisonTabPanel(), "Swing Comparison") } - private fun addSwingTab(toolWindow: ToolWindow) { - val manager = toolWindow.contentManager - val tabContent = - manager.factory.createContent( - ReleasesSamplePanel(toolWindow.disposable.createCoroutineScope()), - "Swing Sample", - true, - ) + private fun ToolWindow.addSwingTab(component: JComponent, @TabTitle title: String) { + val manager = contentManager + val tabContent = manager.factory.createContent(component, title, true) tabContent.isCloseable = false manager.addContent(tabContent) } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/SwingComparisonTabPanel.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/SwingComparisonTabPanel.kt new file mode 100644 index 0000000000..b22f728b51 --- /dev/null +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/SwingComparisonTabPanel.kt @@ -0,0 +1,172 @@ +package org.jetbrains.jewel.samples.ideplugin + +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.calculateEndPadding +import androidx.compose.foundation.layout.calculateStartPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +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 androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI +import com.intellij.ui.JBColor +import com.intellij.ui.components.JBLabel +import com.intellij.ui.components.JBScrollPane +import com.intellij.ui.dsl.builder.AlignY +import com.intellij.ui.dsl.builder.COLUMNS_SHORT +import com.intellij.ui.dsl.builder.Panel +import com.intellij.ui.dsl.builder.Row +import com.intellij.ui.dsl.builder.RowLayout +import com.intellij.ui.dsl.builder.panel +import com.intellij.util.ui.JBFont +import com.intellij.util.ui.JBUI +import com.intellij.util.ui.components.BorderLayoutPanel +import icons.JewelIcons +import org.jetbrains.jewel.bridge.JewelComposePanel +import org.jetbrains.jewel.bridge.medium +import org.jetbrains.jewel.foundation.theme.JewelTheme +import org.jetbrains.jewel.ui.component.DefaultButton +import org.jetbrains.jewel.ui.component.Icon +import org.jetbrains.jewel.ui.component.OutlinedButton +import org.jetbrains.jewel.ui.component.Text +import org.jetbrains.jewel.ui.component.TextArea +import org.jetbrains.jewel.ui.component.TextField +import org.jetbrains.jewel.ui.component.Typography +import org.jetbrains.jewel.ui.theme.textAreaStyle + +internal class SwingComparisonTabPanel : BorderLayoutPanel() { + + private val mainContent = panel { + buttonsRow() + separator() + labelsRows() + separator() + iconsRow() + separator() + textFieldsRow() + separator() + textAreasRow() + }.apply { + border = JBUI.Borders.empty(0, 10) + isOpaque = false + } + + private val scrollingContainer = + JBScrollPane( + mainContent, + JBScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JBScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED, + ) + + init { + addToCenter(scrollingContainer) + scrollingContainer.border = null + scrollingContainer.isOpaque = false + isOpaque = false + } + + private fun Panel.buttonsRow() { + row("Buttons:") { + button("Swing Button") {}.align(AlignY.CENTER) + compose { OutlinedButton({}) { Text("Compose Button") } } + + button("Default Swing Button") {}.align(AlignY.CENTER) + .applyToComponent { putClientProperty(DarculaButtonUI.DEFAULT_STYLE_KEY, true) } + compose { DefaultButton({}) { Text("Default Compose Button") } } + }.layout(RowLayout.PARENT_GRID) + } + + private fun Panel.labelsRows() { + row("Labels:") { + label("Swing label").align(AlignY.CENTER) + compose { Text("Compose label") } + }.layout(RowLayout.PARENT_GRID) + + row("Comments:") { + comment("Swing comment").align(AlignY.CENTER) + compose { + Text("Compose comment", style = Typography.medium(), color = JewelTheme.globalColors.text.info) + } + }.layout(RowLayout.PARENT_GRID) + } + + private fun Panel.iconsRow() { + row("Icons:") { + cell( + JBLabel(JewelIcons.ToolWindowIcon).apply { border = JBUI.Borders.customLine(JBColor.RED) }, + ).align(AlignY.CENTER) + + compose { + Icon( + "icons/jewel-tool-window.svg", + null, + this@SwingComparisonTabPanel.javaClass, + Modifier.border(1.dp, Color.Red), + ) + } + }.layout(RowLayout.PARENT_GRID) + } + + private fun Panel.textFieldsRow() { + row("Text fields:") { + textField().align(AlignY.CENTER) + + compose { + var text by remember { mutableStateOf("") } + TextField(text, { text = it }) + } + }.layout(RowLayout.PARENT_GRID) + } + + private fun Panel.textAreasRow() { + row("Text areas:") { + textArea().align(AlignY.CENTER).applyToComponent { rows = 3 } + + compose { + var text by remember { mutableStateOf("") } + val metrics = remember(JBFont.label(), LocalDensity.current) { getFontMetrics(JBFont.label()) } + val charWidth = remember(metrics.widths) { + // Same logic as in JTextArea + metrics.charWidth('m') + } + val lineHeight = metrics.height + + val width = remember(charWidth) { (COLUMNS_SHORT * charWidth) } + val height = remember(lineHeight) { (3 * lineHeight) } + + val contentPadding = JewelTheme.textAreaStyle.metrics.contentPadding + TextArea( + text, + { text = it }, + Modifier.size( + width = width.dp + contentPadding.horizontal(LocalLayoutDirection.current), + height = height.dp + contentPadding.vertical(), + ), + ) + } + }.layout(RowLayout.PARENT_GRID) + } + + private fun PaddingValues.vertical(): Dp = calculateTopPadding() + calculateBottomPadding() + + private fun PaddingValues.horizontal(layoutDirection: LayoutDirection): Dp = + calculateStartPadding(layoutDirection) + calculateEndPadding(layoutDirection) + + private fun Row.compose(content: @Composable () -> Unit) = + cell( + JewelComposePanel { + Box(Modifier.padding(8.dp)) { content() } + }.apply { isOpaque = false }, + ) +} 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 c0476e64b0..aef8686d95 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 @@ -506,7 +506,7 @@ private fun ItemDetailsText(selectedItem: ContentItem) { Text( text = "Released on ${formatter.format(releaseDate.toJavaLocalDate())}", style = Typography.medium(), - color = JBUI.CurrentTheme.Label.disabledForeground().toComposeColor(), + color = JewelTheme.globalColors.text.info, ) }