diff --git a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/ComposeDemoAction.kt b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/ComposeDemoAction.kt old mode 100644 new mode 100755 index a66f5a6fd0..764ce9bca9 --- a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/ComposeDemoAction.kt +++ b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/ComposeDemoAction.kt @@ -1,18 +1,22 @@ package com.jetbrains.compose import androidx.compose.desktop.ComposePanel -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.size -import androidx.compose.material.Button +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.IntSize import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.project.DumbAwareAction import com.intellij.openapi.project.Project import com.intellij.openapi.ui.DialogWrapper import com.intellij.ui.layout.panel +import com.jetbrains.compose.widgets.Buttons +import com.jetbrains.compose.widgets.LazyScrollable +import com.jetbrains.compose.widgets.Loaders +import com.jetbrains.compose.widgets.TextInputs +import com.jetbrains.compose.widgets.Toggles import java.awt.Dimension import javax.swing.JComponent @@ -32,19 +36,33 @@ class ComposeDemoAction : DumbAwareAction() { } override fun createCenterPanel(): JComponent { + val dialog = this + var packed = false return ComposePanel().apply { setContent { - Button(onClick = { println("Hi") }) { - //Text("Hello") //todo: crashes IntelliJ - Box( - modifier = Modifier - .background(color = Color.Red) - .size(20.dp, 20.dp) - ) + ComposeSizeAdjustmentWrapper( + window = dialog, + panel = this, + preferredSize = IntSize(800, 600) + ) { + Row { + Column( + modifier = Modifier.fillMaxHeight().weight(1f) + ) { + Buttons() + Loaders() + TextInputs() + Toggles() + } + Box( + modifier = Modifier.fillMaxHeight().weight(1f) + ) { + LazyScrollable() + } + } } } - size = Dimension(50, 50) } } } -} \ No newline at end of file +} diff --git a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/ComposeSizeAdjustmentWrapper.kt b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/ComposeSizeAdjustmentWrapper.kt new file mode 100755 index 0000000000..bf6170470f --- /dev/null +++ b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/ComposeSizeAdjustmentWrapper.kt @@ -0,0 +1,45 @@ +package com.jetbrains.compose + +import androidx.compose.desktop.ComposePanel +import androidx.compose.foundation.layout.Box +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.Layout +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.unit.IntSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import com.intellij.openapi.ui.DialogWrapper +import java.awt.Dimension +import java.awt.Window +import javax.swing.JComponent + +@Composable +fun ComposeSizeAdjustmentWrapper( + window: DialogWrapper, + panel: ComposePanel, + preferredSize: IntSize, + content: @Composable () -> Unit +) { + var packed = false + Box { + content() + Layout( + content = {}, + modifier = Modifier.onGloballyPositioned { childCoordinates -> + // adjust size of the dialog + if (!packed) { + val contentSize = childCoordinates.parentCoordinates!!.size + panel.preferredSize = Dimension( + if (contentSize.width < preferredSize.width) preferredSize.width else contentSize.width, + if (contentSize.height < preferredSize.height) preferredSize.height else contentSize.height, + ) + window.pack() + packed = true + } + }, + measureBlock = { _, _ -> + layout(0, 0) {} + } + ) + } +} diff --git a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Buttons.kt b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Buttons.kt new file mode 100755 index 0000000000..a30d9b64cc --- /dev/null +++ b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Buttons.kt @@ -0,0 +1,49 @@ +package com.jetbrains.compose.widgets + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Button +import androidx.compose.material.TextButton +import androidx.compose.material.OutlinedButton +import androidx.compose.material.Text +import androidx.compose.material.Icon +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.FavoriteBorder +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun Buttons() { + Row { + val btnEnabled = remember { mutableStateOf(true) } + Button( + onClick = { btnEnabled.value = !btnEnabled.value}, + modifier = Modifier.padding(8.dp), + enabled = btnEnabled.value + ) { + Icon(Icons.Default.FavoriteBorder, modifier = Modifier.padding(end = 4.dp)) + Text(text = "Button") + } + val btnTextEnabled = remember { mutableStateOf(true) } + TextButton( + onClick = { btnTextEnabled.value = !btnTextEnabled.value }, + modifier = Modifier.padding(8.dp), + enabled = btnTextEnabled.value + ) { + Text(text = "Text Button") + } + OutlinedButton( + onClick = { + btnEnabled.value = true + btnTextEnabled.value = true + }, + modifier = Modifier.padding(8.dp) + ) { + Icon(Icons.Default.Refresh, modifier = Modifier.padding(0.dp)) + } + } +} \ No newline at end of file diff --git a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/LazyScrollable.kt b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/LazyScrollable.kt new file mode 100755 index 0000000000..7b9344340d --- /dev/null +++ b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/LazyScrollable.kt @@ -0,0 +1,63 @@ +package com.jetbrains.compose.widgets + +import androidx.compose.desktop.DesktopTheme +import androidx.compose.foundation.background +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.rememberScrollbarAdapter +import androidx.compose.foundation.Text +import androidx.compose.foundation.VerticalScrollbar +import androidx.compose.material.MaterialTheme +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun LazyScrollable() { + MaterialTheme { + DesktopTheme { + Box( + modifier = Modifier.fillMaxSize() + .background(color = Color(180, 180, 180)) + .padding(10.dp) + ) { + + val state = rememberLazyListState() + val itemCount = 100 + + LazyColumn(Modifier.fillMaxSize().padding(end = 12.dp), state) { + items((1..itemCount).toList()) { x -> + TextBox("Item in ScrollableColumn #$x") + Spacer(modifier = Modifier.height(5.dp)) + } + } + VerticalScrollbar( + modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(), + adapter = rememberScrollbarAdapter( + scrollState = state, + itemCount = itemCount, + averageItemSize = 37.dp // TextBox height + Spacer height + ) + ) + } + } + } +} + +@Composable +private fun TextBox(text: String = "Item") { + Box( + modifier = Modifier.height(32.dp) + .fillMaxWidth() + .background(color = Color(0, 0, 0, 20)) + .padding(start = 10.dp), + contentAlignment = Alignment.CenterStart + ) { + Text(text = text) + } +} \ No newline at end of file diff --git a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Loaders.kt b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Loaders.kt new file mode 100755 index 0000000000..a18252459b --- /dev/null +++ b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Loaders.kt @@ -0,0 +1,39 @@ +package com.jetbrains.compose.widgets + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.material.LinearProgressIndicator +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun Loaders() { + Row( + modifier = Modifier.fillMaxWidth().padding(16.dp) + ) { + Box( + modifier = Modifier.height(30.dp), + contentAlignment = Alignment.Center + ) { + CircularProgressIndicator( + modifier = Modifier.size(20.dp, 20.dp), + strokeWidth = 4.dp + ) + } + Box( + modifier = Modifier + .height(30.dp) + .padding(start = 8.dp), + contentAlignment = Alignment.Center + ) { + LinearProgressIndicator(modifier = Modifier.fillMaxWidth()) + } + } +} \ No newline at end of file diff --git a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/TextInputs.kt b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/TextInputs.kt new file mode 100755 index 0000000000..672a2d7120 --- /dev/null +++ b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/TextInputs.kt @@ -0,0 +1,47 @@ +package com.jetbrains.compose.widgets + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.Text +import androidx.compose.material.TextField +import androidx.compose.material.OutlinedTextField +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.TextFieldValue +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.unit.dp + +@Composable +fun TextInputs() { + Column( + modifier = Modifier.fillMaxWidth().padding(16.dp) + ) { + var name by remember { mutableStateOf(TextFieldValue("")) } + var password by remember { mutableStateOf(TextFieldValue("")) } + TextField( + value = name, + onValueChange = { newValue -> name = newValue }, + modifier = Modifier.padding(8.dp).fillMaxWidth(), + label = { Text("Account:") }, + placeholder = { Text("account name") } + ) + OutlinedTextField( + value = password, + modifier = Modifier.padding(8.dp).fillMaxWidth(), + label = { Text(text = "Password:") }, + placeholder = { Text(text = "your password") }, + visualTransformation = PasswordVisualTransformation(), + onValueChange = { + password = it + }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) + ) + } +} \ No newline at end of file diff --git a/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Toggles.kt b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Toggles.kt new file mode 100755 index 0000000000..35f5466f8b --- /dev/null +++ b/examples/intelliJPlugin/src/main/kotlin/com/jetbrains/compose/widgets/Toggles.kt @@ -0,0 +1,90 @@ +package com.jetbrains.compose.widgets + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.Checkbox +import androidx.compose.material.MaterialTheme +import androidx.compose.material.RadioButton +import androidx.compose.material.Slider +import androidx.compose.material.Switch +import androidx.compose.material.SwitchConstants +import androidx.compose.material.Text +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.unit.dp + +@Composable +fun Toggles() { + Column { + Row { + Column( + modifier = Modifier.padding(16.dp) + ) { + var checked by remember { mutableStateOf(true) } + Checkbox( + checked = checked, + modifier = Modifier.padding(8.dp), + onCheckedChange = { checked = !checked } + ) + var switched by remember { mutableStateOf(true) } + Switch( + checked = switched, + colors = SwitchConstants.defaultColors(checkedThumbColor = MaterialTheme.colors.primary), + modifier = Modifier.padding(8.dp), + onCheckedChange = { switched = it } + ) + } + Column( + modifier = Modifier.padding(16.dp) + ) { + var selected by remember { mutableStateOf("Kotlin") } + Row { + RadioButton(selected = selected == "Kotlin", onClick = { selected = "Kotlin" }) + Text( + text = "Kotlin", + modifier = Modifier.clickable(onClick = { selected = "Kotlin" }).padding(start = 4.dp) + ) + } + Row { + RadioButton(selected = selected == "Java", onClick = { selected = "Java" }) + Text( + text = "Java", + modifier = Modifier.clickable(onClick = { selected = "Java" }).padding(start = 4.dp) + ) + } + Row { + RadioButton(selected = selected == "Swift", onClick = { selected = "Swift" }) + Text( + text = "Swift", + modifier = Modifier.clickable(onClick = { selected = "Swift" }).padding(start = 4.dp) + ) + } + } + } + + var sliderState by remember { mutableStateOf(0f) } + Slider(value = sliderState, modifier = Modifier.fillMaxWidth().padding(8.dp), + onValueChange = { newValue -> + sliderState = newValue + } + ) + + var sliderState2 by remember { mutableStateOf(20f) } + Slider(value = sliderState2, modifier = Modifier.fillMaxWidth().padding(8.dp), + valueRange = 0f..100f, + steps = 5, + thumbColor = MaterialTheme.colors.secondary, + onValueChange = { newValue -> + sliderState2 = newValue + } + ) + } +} \ No newline at end of file