Skip to content

Commit

Permalink
Initial Compose impl (left column)
Browse files Browse the repository at this point in the history
  • Loading branch information
rock3r committed Oct 6, 2023
1 parent 43b1c4e commit e8b1bb1
Show file tree
Hide file tree
Showing 22 changed files with 672 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ open class StudioVersionsGenerationExtension(project: Project) {
.convention("https://jb.gg/android-studio-releases-list.json")
}

private const val OUTPUT_CLASS_NAME = "org.jetbrains.jewel.samples.ideplugin.AndroidStudioReleases"
private const val OUTPUT_CLASS_NAME = "org.jetbrains.jewel.samples.ideplugin.releasessample.AndroidStudioReleases"

open class AndroidStudioReleasesGeneratorTask : DefaultTask() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import java.io.File
import java.time.ZonedDateTime

private val ContentItemClassName =
ClassName.bestGuess("org.jetbrains.jewel.samples.ideplugin.ContentItem.AndroidStudio")
ClassName.bestGuess("org.jetbrains.jewel.samples.ideplugin.releasessample.ContentItem.AndroidStudio")

internal object AndroidStudioReleasesReader {

Expand All @@ -28,13 +28,13 @@ internal object AndroidStudioReleasesReader {
addFileComment("Generated by the Jewel Android Studio Releases Generator\n")
addFileComment("Generated from $url on ${ZonedDateTime.now()}\n")

addImport("org.jetbrains.jewel.samples.ideplugin", "ContentItem.AndroidStudio")
addImport("org.jetbrains.jewel.samples.ideplugin.releasessample", "ContentItem.AndroidStudio")
addImport("kotlinx.datetime", "LocalDate")

addType(
TypeSpec.objectBuilder(className)
.superclass(
ClassName.bestGuess("org.jetbrains.jewel.samples.ideplugin.ContentSource")
ClassName.bestGuess("org.jetbrains.jewel.samples.ideplugin.releasessample.ContentSource")
.parameterizedBy(ContentItemClassName)
)
.apply {
Expand All @@ -47,6 +47,16 @@ internal object AndroidStudioReleasesReader {
.initializer(readReleases(releases, resourceDirs))
.build()
)

addProperty(
PropertySpec.builder(
"displayName",
type = String::class.asClassName(),
KModifier.OVERRIDE
)
.initializer("\"%L\"", "Android Studio releases")
.build()
)
}.build()
)
}.build()
Expand Down
62 changes: 1 addition & 61 deletions core/src/main/kotlin/org/jetbrains/jewel/Dropdown.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.input.InputMode
import androidx.compose.ui.input.InputModeManager
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.res.ResourceLoader
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties
import org.jetbrains.jewel.CommonStateBitMask.Active
import org.jetbrains.jewel.CommonStateBitMask.Enabled
import org.jetbrains.jewel.CommonStateBitMask.Focused
Expand All @@ -43,8 +36,6 @@ import org.jetbrains.jewel.CommonStateBitMask.Pressed
import org.jetbrains.jewel.foundation.Stroke
import org.jetbrains.jewel.foundation.border
import org.jetbrains.jewel.styling.DropdownStyle
import org.jetbrains.jewel.styling.LocalMenuStyle
import org.jetbrains.jewel.styling.MenuStyle
import org.jetbrains.jewel.util.appendIf

@Composable
Expand Down Expand Up @@ -148,7 +139,7 @@ fun Dropdown(
}

if (expanded) {
DropdownMenu(
PopupMenu(
onDismissRequest = {
expanded = false
if (it == InputMode.Touch && dropdownState.isHovered) {
Expand All @@ -166,57 +157,6 @@ fun Dropdown(
}
}

@Composable
internal fun DropdownMenu(
onDismissRequest: (InputMode) -> Boolean,
horizontalAlignment: Alignment.Horizontal,
resourceLoader: ResourceLoader,
modifier: Modifier = Modifier,
style: MenuStyle,
content: MenuScope.() -> Unit,
) {
val density = LocalDensity.current

val popupPositionProvider = AnchorVerticalMenuPositionProvider(
contentOffset = style.metrics.offset,
contentMargin = style.metrics.menuMargin,
alignment = horizontalAlignment,
density = density,
)

var focusManager: FocusManager? by mutableStateOf(null)
var inputModeManager: InputModeManager? by mutableStateOf(null)
val menuManager = remember(onDismissRequest) {
MenuManager(onDismissRequest = onDismissRequest)
}

Popup(
popupPositionProvider = popupPositionProvider,
onDismissRequest = { onDismissRequest(InputMode.Touch) },
properties = PopupProperties(focusable = true),
onPreviewKeyEvent = { false },
onKeyEvent = {
val currentFocusManager = checkNotNull(focusManager) { "FocusManager must not be null" }
val currentInputModeManager = checkNotNull(inputModeManager) { "InputModeManager must not be null" }
handlePopupMenuOnKeyEvent(it, currentFocusManager, currentInputModeManager, menuManager)
},
) {
focusManager = LocalFocusManager.current
inputModeManager = LocalInputModeManager.current

CompositionLocalProvider(
LocalMenuManager provides menuManager,
LocalMenuStyle provides style,
) {
MenuContent(
modifier = modifier,
content = content,
resourceLoader = resourceLoader,
)
}
}
}

@Immutable
@JvmInline
value class DropdownState(val state: ULong) : FocusableComponentState {
Expand Down
1 change: 1 addition & 0 deletions core/src/main/kotlin/org/jetbrains/jewel/GlobalMetrics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.ui.unit.Dp
interface GlobalMetrics {

val outlineWidth: Dp
val rowHeight: Dp
}

val LocalGlobalMetrics = staticCompositionLocalOf<GlobalMetrics> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.io.InputStream

abstract class JewelResourceLoader : ResourceLoader {

protected var verbose = true
private var verbose = true

protected fun loadResourceOrNull(path: String, classLoaders: List<ClassLoader>): InputStream? {
for (classLoader in classLoaders) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/kotlin/org/jetbrains/jewel/Link.kt
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fun DropdownLink(
)

if (expanded) {
DropdownMenu(
PopupMenu(
onDismissRequest = {
expanded = false
if (it == InputMode.Touch && hovered) {
Expand Down
52 changes: 52 additions & 0 deletions core/src/main/kotlin/org/jetbrains/jewel/Menu.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,62 @@ import org.jetbrains.jewel.CommonStateBitMask.Active
import org.jetbrains.jewel.foundation.Stroke
import org.jetbrains.jewel.foundation.border
import org.jetbrains.jewel.foundation.onHover
import org.jetbrains.jewel.styling.LocalMenuStyle
import org.jetbrains.jewel.styling.MenuItemColors
import org.jetbrains.jewel.styling.MenuItemMetrics
import org.jetbrains.jewel.styling.MenuStyle

@Composable
fun PopupMenu(
onDismissRequest: (InputMode) -> Boolean,
horizontalAlignment: Alignment.Horizontal,
resourceLoader: ResourceLoader,
modifier: Modifier = Modifier,
style: MenuStyle = IntelliJTheme.menuStyle,
content: MenuScope.() -> Unit,
) {
val density = LocalDensity.current

val popupPositionProvider = AnchorVerticalMenuPositionProvider(
contentOffset = style.metrics.offset,
contentMargin = style.metrics.menuMargin,
alignment = horizontalAlignment,
density = density,
)

var focusManager: FocusManager? by mutableStateOf(null)
var inputModeManager: InputModeManager? by mutableStateOf(null)
val menuManager = remember(onDismissRequest) {
MenuManager(onDismissRequest = onDismissRequest)
}

Popup(
popupPositionProvider = popupPositionProvider,
onDismissRequest = { onDismissRequest(InputMode.Touch) },
properties = PopupProperties(focusable = true),
onPreviewKeyEvent = { false },
onKeyEvent = {
val currentFocusManager = checkNotNull(focusManager) { "FocusManager must not be null" }
val currentInputModeManager = checkNotNull(inputModeManager) { "InputModeManager must not be null" }
handlePopupMenuOnKeyEvent(it, currentFocusManager, currentInputModeManager, menuManager)
},
) {
focusManager = LocalFocusManager.current
inputModeManager = LocalInputModeManager.current

CompositionLocalProvider(
LocalMenuManager provides menuManager,
LocalMenuStyle provides style,
) {
MenuContent(
modifier = modifier,
content = content,
resourceLoader = resourceLoader,
)
}
}
}

@Composable
internal fun MenuContent(
resourceLoader: ResourceLoader,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import androidx.compose.runtime.Immutable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil
import com.intellij.ui.scale.JBUIScale
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
import org.jetbrains.jewel.GlobalMetrics

@Immutable
internal class BridgeGlobalMetrics(
override val outlineWidth: Dp,
override val rowHeight: Dp,
) : GlobalMetrics {

override fun equals(other: Any?): Boolean {
Expand All @@ -19,14 +22,19 @@ internal class BridgeGlobalMetrics(
other as BridgeGlobalMetrics

if (outlineWidth != other.outlineWidth) return false
if (rowHeight != other.rowHeight) return false

return true
}

override fun hashCode(): Int = outlineWidth.hashCode()
override fun hashCode(): Int {
var result = outlineWidth.hashCode()
result = 31 * result + rowHeight.hashCode()
return result
}

override fun toString(): String =
"BridgeGlobalMetrics(outlineWidth=$outlineWidth)"
override fun toString() =
"BridgeGlobalMetrics(outlineWidth=$outlineWidth, rowHeight=$rowHeight)"

companion object {

Expand All @@ -36,7 +44,11 @@ internal class BridgeGlobalMetrics(
val f = if (UIUtil.isRetina()) 0.5f else 1.0f
val lw = if (UIUtil.isUnderDefaultMacTheme()) f else DarculaUIUtil.LW.unscaled

return BridgeGlobalMetrics(outlineWidth = (DarculaUIUtil.BW.unscaled + lw).dp)
return BridgeGlobalMetrics(
outlineWidth = (DarculaUIUtil.BW.unscaled + lw).dp,
// The rowHeight() function returns a scaled value, but we need the base value
rowHeight = (JBUI.CurrentTheme.List.rowHeight() / JBUIScale.scale(1f)).dp
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.jetbrains.jewel.GlobalMetrics
@Immutable
class IntUiGlobalMetrics(
override val outlineWidth: Dp = 2.dp,
override val rowHeight: Dp = 24.dp
) : GlobalMetrics {

override fun equals(other: Any?): Boolean {
Expand All @@ -16,11 +17,18 @@ class IntUiGlobalMetrics(

other as IntUiGlobalMetrics

return outlineWidth == other.outlineWidth
if (outlineWidth != other.outlineWidth) return false
if (rowHeight != other.rowHeight) return false

return true
}

override fun hashCode(): Int = outlineWidth.hashCode()
override fun hashCode(): Int {
var result = outlineWidth.hashCode()
result = 31 * result + rowHeight.hashCode()
return result
}

override fun toString(): String =
"IntUiGlobalMetrics(outlineWidth=$outlineWidth)"
override fun toString() =
"IntUiGlobalMetrics(outlineWidth=$outlineWidth, rowHeight=$rowHeight)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import org.jetbrains.jewel.bridge.addComposeTab
import org.jetbrains.jewel.samples.ideplugin.swingsample.SwingDemoPanel
import org.jetbrains.jewel.samples.ideplugin.releasessample.ReleasesSampleCompose
import org.jetbrains.jewel.samples.ideplugin.releasessample.ReleasesSamplePanel

@ExperimentalCoroutinesApi
internal class JewelDemoToolWindowFactory : ToolWindowFactory, DumbAware {
Expand All @@ -25,14 +26,15 @@ internal class JewelDemoToolWindowFactory : ToolWindowFactory, DumbAware {
addSwingTab(toolWindow)

toolWindow.addComposeTab("Compose Sample") {
ReleasesSampleCompose(project)
}
}

private fun addSwingTab(toolWindow: ToolWindow) {
val manager = toolWindow.contentManager
val tabContent =
manager.factory.createContent(
SwingDemoPanel(toolWindow.disposable.createCoroutineScope()),
ReleasesSamplePanel(toolWindow.disposable.createCoroutineScope()),
"Swing Sample",
true,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.jetbrains.jewel.samples.ideplugin.swingsample
package org.jetbrains.jewel.samples.ideplugin.releasessample

import com.intellij.openapi.ui.GraphicsConfig
import com.intellij.ui.paint.RectanglePainter
import com.intellij.ui.scale.JBUIScale
import com.intellij.util.ui.JBFont
import com.intellij.util.ui.JBUI
import org.jetbrains.jewel.samples.ideplugin.ReleaseChannel
import java.awt.Graphics
import java.awt.Graphics2D
import javax.swing.JLabel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.jetbrains.jewel.samples.ideplugin.swingsample
package org.jetbrains.jewel.samples.ideplugin.releasessample

import com.intellij.openapi.ui.GraphicsConfig
import com.intellij.ui.paint.RectanglePainter
import com.intellij.ui.scale.JBUIScale
import com.intellij.util.ui.JBFont
import com.intellij.util.ui.JBUI
import org.jetbrains.jewel.samples.ideplugin.ReleaseChannel
import java.awt.Graphics
import java.awt.Graphics2D
import javax.swing.JLabel
Expand Down
Loading

0 comments on commit e8b1bb1

Please sign in to comment.