diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt index 072675e9..65db586a 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.input.key.Key.Companion.G import androidx.compose.ui.input.key.Key.Companion.L import androidx.compose.ui.input.key.Key.Companion.O import androidx.compose.ui.input.key.Key.Companion.P +import androidx.compose.ui.text.style.TextAlign.Companion.Center import androidx.compose.ui.unit.dp import androidx.compose.ui.window.* import dev.romainguy.kotlin.explorer.Shortcut.Ctrl @@ -120,6 +121,11 @@ private fun FrameWindowScope.KotlinExplorer( val findDialog = remember { FindDialog(window, searchListener).apply { searchContext.searchWrap = true } } var showSettings by remember { mutableStateOf(!explorerState.toolPaths.isValid) } + val sourcePanel: @Composable () -> Unit = { SourcePanel(sourceTextArea, explorerState) } + val dexPanel: @Composable () -> Unit = { TextPanel("DEX", dexTextArea, explorerState) } + val oatPanel: @Composable () -> Unit = { TextPanel("OAT", oatTextArea, explorerState) } + var panels by remember { mutableStateOf(explorerState.getPanels(sourcePanel, dexPanel, oatPanel)) } + MainMenu( explorerState, sourceTextArea, @@ -135,7 +141,8 @@ private fun FrameWindowScope.KotlinExplorer( { statusUpdate -> status = statusUpdate }, { findDialog.isVisible = true }, { SearchEngine.find(activeTextArea, findDialog.searchContext) }, - { showSettings = true } + { showSettings = true }, + { panels = explorerState.getPanels(sourcePanel, dexPanel, oatPanel) }, ) if (showSettings) { @@ -147,12 +154,7 @@ private fun FrameWindowScope.KotlinExplorer( Column( modifier = Modifier.background(JewelTheme.globalColors.paneBackground) ) { - MultiSplitter( - modifier = Modifier.weight(1.0f), - { SourcePanel(sourceTextArea, explorerState) }, - { TextPanel(dexTextArea, explorerState) }, - { TextPanel(oatTextArea, explorerState) }, - ) + MultiSplitter(modifier = Modifier.weight(1.0f), panels) Row { Text( modifier = Modifier @@ -166,26 +168,59 @@ private fun FrameWindowScope.KotlinExplorer( } } +private fun ExplorerState.getPanels( + sourcePanel: @Composable () -> Unit, + dexPanel: @Composable () -> Unit, + oatPanel: @Composable () -> Unit, +): List<@Composable () -> Unit> { + return buildList { + add(sourcePanel) + if (showDex) { + add(dexPanel) + } + if (showOat) { + add(oatPanel) + } + } +} + @Composable private fun SourcePanel(sourceTextArea: RSyntaxTextArea, explorerState: ExplorerState) { - SwingPanel( - modifier = Modifier.fillMaxSize(), - factory = { - RTextScrollPane(sourceTextArea) - }, - update = { - sourceTextArea.text = explorerState.sourceCode - sourceTextArea.setFont(explorerState) - } - ) + Column { + Title("Source") + SwingPanel( + modifier = Modifier.fillMaxSize(), + factory = { + RTextScrollPane(sourceTextArea) + }, + update = { + sourceTextArea.text = explorerState.sourceCode + sourceTextArea.setFont(explorerState) + } + ) + } } @Composable -private fun TextPanel(textArea: RSyntaxTextArea, explorerState: ExplorerState) { - SwingPanel( - modifier = Modifier.fillMaxSize(), - factory = { RTextScrollPane(textArea) }, - update = { textArea.setFont(explorerState) }) +private fun TextPanel(title: String, textArea: RSyntaxTextArea, explorerState: ExplorerState) { + Column { + Title(title) + SwingPanel( + modifier = Modifier.fillMaxSize(), + factory = { RTextScrollPane(textArea) }, + update = { textArea.setFont(explorerState) }) + } +} + +@Composable +private fun Title(text: String) { + Text( + text, + textAlign = Center, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp) + ) } private fun sourceTextArea(focusTracker: FocusListener, explorerState: ExplorerState): RSyntaxTextArea { @@ -220,7 +255,8 @@ private fun FrameWindowScope.MainMenu( onStatusUpdate: (String) -> Unit, onFindClicked: () -> Unit, onFindNextClicked: () -> Unit, - onOpenSettings: () -> Unit + onOpenSettings: () -> Unit, + onPanelsUpdated: () -> Unit, ) { val scope = rememberCoroutineScope() @@ -245,6 +281,9 @@ private fun FrameWindowScope.MainMenu( MenuItem("Find Next Occurrence", Ctrl(G), onClick = onFindNextClicked) } Menu("View") { + val onShowPanelChanged: (Boolean) -> Unit = { onPanelsUpdated() } + MenuCheckboxItem("Show DEX", Ctrl(D), explorerState::showDex, onShowPanelChanged) + MenuCheckboxItem("Show OAT", Ctrl(O), explorerState::showOat, onShowPanelChanged) MenuCheckboxItem("Presentation Mode", CtrlShift(P), explorerState::presentationMode) MenuCheckboxItem("Show Line Numbers", CtrlShift(L), explorerState::showLineNumbers) { onDexUpdate(null) diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/Splitter.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/Splitter.kt index 0e3dbb72..629ac383 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/Splitter.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/Splitter.kt @@ -19,7 +19,9 @@ package dev.romainguy.kotlin.explorer -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.width import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.PointerIcon @@ -54,7 +56,7 @@ fun SplitterScope.HorizontalSplitter() { } @Composable -fun MultiSplitter(modifier: Modifier = Modifier, vararg panels: @Composable () -> Unit) { +fun MultiSplitter(modifier: Modifier = Modifier, panels: List<@Composable () -> Unit>) { val size = panels.size if (size == 1) { panels[0]() @@ -64,7 +66,7 @@ fun MultiSplitter(modifier: Modifier = Modifier, vararg panels: @Composable () - splitPaneState = rememberSplitPaneState(initialPositionPercentage = 1.0f / size) ) { first { panels[0]() } - second { MultiSplitter(modifier = modifier, *panels.drop(1).toTypedArray()) } + second { MultiSplitter(modifier = modifier, panels.drop(1)) } splitter { HorizontalSplitter() } } diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt index c8b00055..b9a6c502 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt @@ -26,6 +26,8 @@ import kotlin.io.path.readLines private const val Optimize = "OPTIMIZE" private const val Presentation = "PRESENTATION" private const val ShowLineNumbers = "SHOW_LINE_NUMBERS" +private const val ShowDex = "SHOW_DEX" +private const val ShowOat = "SHOW_OAT" @Stable class ExplorerState( @@ -35,6 +37,8 @@ class ExplorerState( var optimize by BooleanState(Optimize, true) var presentationMode by BooleanState(Presentation, false) var showLineNumbers by BooleanState(ShowLineNumbers, true) + var showDex by BooleanState(ShowDex, true) + var showOat by BooleanState(ShowOat, true) var sourceCode: String = readSourceCode(toolPaths) fun reloadToolPathsFromSettings() {