Browse Source

Publish components (#829)

pull/830/head
Igor Demin 3 years ago committed by GitHub
parent
commit
854de3681c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      components/SplitPane/build.gradle.kts
  2. 56
      components/SplitPane/demo/build.gradle.kts
  3. 180
      components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt
  4. 61
      components/SplitPane/library/build.gradle.kts
  5. 0
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/ExperimentalSplitPaneApi.kt
  6. 0
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPane.kt
  7. 0
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneDSL.kt
  8. 0
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt
  9. 0
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/Splitter.kt
  10. 280
      components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitPane.kt
  11. 202
      components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitter.kt
  12. 21
      components/VideoPlayer/build.gradle.kts
  13. 2
      components/VideoPlayer/demo/build.gradle.kts
  14. 0
      components/VideoPlayer/demo/src/jvmMain/kotlin/org/jetbrains/compose/videoplayer/demo/Main.kt
  15. 0
      components/VideoPlayer/library/build.gradle.kts
  16. 0
      components/VideoPlayer/library/src/commonMain/kotlin/org/jetbrains/compose/videoplayer/VideoPlayer.kt
  17. 0
      components/VideoPlayer/library/src/desktopMain/kotlin/org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt
  18. 34
      components/build.gradle.kts
  19. 11
      components/buildSrc/build.gradle.kts
  20. 5
      components/buildSrc/settings.gradle.kts
  21. 32
      components/buildSrc/src/main/kotlin/CommonMavenProperties.kt
  22. 19
      components/buildSrc/src/main/kotlin/GradleUtils.kt
  23. 5
      components/gradle.properties
  24. 8
      components/settings.gradle.kts
  25. 6
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt

21
components/SplitPane/build.gradle.kts

@ -1,21 +0,0 @@
import org.jetbrains.compose.compose
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
jvm {
withJava()
}
sourceSets {
named("jvmMain") {
dependencies {
implementation(compose.desktop.currentOs)
implementation(project("common"))
}
}
}
}

56
components/SplitPane/desktop/build.gradle.kts → components/SplitPane/demo/build.gradle.kts

@ -1,29 +1,29 @@
import org.jetbrains.compose.compose
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
jvm {}
sourceSets {
named("jvmMain") {
dependencies {
implementation(compose.desktop.currentOs)
implementation(project(":SplitPane:common"))
}
}
}
}
compose.desktop {
application {
mainClass = "org.jetbrains.compose.splitpane.demo.MainKt"
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
import org.jetbrains.compose.compose
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
jvm {}
sourceSets {
named("jvmMain") {
dependencies {
implementation(compose.desktop.currentOs)
implementation(project(":SplitPane:library"))
}
}
}
}
compose.desktop {
application {
mainClass = "org.jetbrains.compose.splitpane.demo.MainKt"
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}

180
components/SplitPane/desktop/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt → components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt

@ -1,91 +1,91 @@
package org.jetbrains.compose.splitpane.demo
import androidx.compose.desktop.DesktopTheme
import androidx.compose.desktop.LocalAppWindow
import androidx.compose.desktop.Window
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.width
import androidx.compose.material.MaterialTheme
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.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.input.pointer.pointerMoveFilter
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
import org.jetbrains.compose.splitpane.HorizontalSplitPane
import org.jetbrains.compose.splitpane.VerticalSplitPane
import org.jetbrains.compose.splitpane.rememberSplitPaneState
import java.awt.Cursor
private fun Modifier.cursorForHorizontalResize(
): Modifier = composed {
var isHover by remember { mutableStateOf(false) }
if (isHover) {
LocalAppWindow.current.window.cursor = Cursor(Cursor.E_RESIZE_CURSOR)
} else {
LocalAppWindow.current.window.cursor = Cursor.getDefaultCursor()
}
pointerMoveFilter(
onEnter = { isHover = true; true },
onExit = { isHover = false; true }
)
}
@OptIn(ExperimentalSplitPaneApi::class)
fun main() = Window(
"SplitPane demo"
) {
MaterialTheme {
DesktopTheme {
val splitterState = rememberSplitPaneState()
val hSplitterState = rememberSplitPaneState()
HorizontalSplitPane(
splitPaneState = splitterState
) {
first(20.dp) {
Box(Modifier.background(Color.Red).fillMaxSize())
}
second(50.dp) {
VerticalSplitPane(splitPaneState = hSplitterState) {
first(50.dp) {
Box(Modifier.background(Color.Blue).fillMaxSize())
}
second(20.dp) {
Box(Modifier.background(Color.Green).fillMaxSize())
}
}
}
splitter {
visiblePart {
Box(
Modifier
.width(1.dp)
.fillMaxHeight()
.background(MaterialTheme.colors.background)
)
}
handle {
Box(
Modifier
.markAsHandle()
.cursorForHorizontalResize()
.background(SolidColor(Color.Gray), alpha = 0.50f)
.width(9.dp)
.fillMaxHeight()
)
}
}
}
}
}
package org.jetbrains.compose.splitpane.demo
import androidx.compose.desktop.DesktopTheme
import androidx.compose.desktop.LocalAppWindow
import androidx.compose.desktop.Window
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.width
import androidx.compose.material.MaterialTheme
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.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.input.pointer.pointerMoveFilter
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
import org.jetbrains.compose.splitpane.HorizontalSplitPane
import org.jetbrains.compose.splitpane.VerticalSplitPane
import org.jetbrains.compose.splitpane.rememberSplitPaneState
import java.awt.Cursor
private fun Modifier.cursorForHorizontalResize(
): Modifier = composed {
var isHover by remember { mutableStateOf(false) }
if (isHover) {
LocalAppWindow.current.window.cursor = Cursor(Cursor.E_RESIZE_CURSOR)
} else {
LocalAppWindow.current.window.cursor = Cursor.getDefaultCursor()
}
pointerMoveFilter(
onEnter = { isHover = true; true },
onExit = { isHover = false; true }
)
}
@OptIn(ExperimentalSplitPaneApi::class)
fun main() = Window(
"SplitPane demo"
) {
MaterialTheme {
DesktopTheme {
val splitterState = rememberSplitPaneState()
val hSplitterState = rememberSplitPaneState()
HorizontalSplitPane(
splitPaneState = splitterState
) {
first(20.dp) {
Box(Modifier.background(Color.Red).fillMaxSize())
}
second(50.dp) {
VerticalSplitPane(splitPaneState = hSplitterState) {
first(50.dp) {
Box(Modifier.background(Color.Blue).fillMaxSize())
}
second(20.dp) {
Box(Modifier.background(Color.Green).fillMaxSize())
}
}
}
splitter {
visiblePart {
Box(
Modifier
.width(1.dp)
.fillMaxHeight()
.background(MaterialTheme.colors.background)
)
}
handle {
Box(
Modifier
.markAsHandle()
.cursorForHorizontalResize()
.background(SolidColor(Color.Gray), alpha = 0.50f)
.width(9.dp)
.fillMaxHeight()
)
}
}
}
}
}
}

61
components/SplitPane/common/build.gradle.kts → components/SplitPane/library/build.gradle.kts

@ -1,27 +1,34 @@
import org.jetbrains.compose.compose
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
jvm("desktop")
sourceSets {
named("commonMain") {
dependencies {
api(compose.runtime)
api(compose.foundation)
api(compose.material)
}
}
named("desktopMain") {}
}
}
// TODO it seems that argument isn't applied to the common sourceSet. Figure out why
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
import org.jetbrains.compose.compose
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
id("maven-publish")
}
kotlin {
jvm("desktop")
sourceSets {
named("commonMain") {
dependencies {
api(compose.runtime)
api(compose.foundation)
api(compose.material)
}
}
named("desktopMain") {}
}
}
// TODO it seems that argument isn't applied to the common sourceSet. Figure out why
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
configureMavenPublication(
groupId = "org.jetbrains.compose.components",
artifactId = "components-splitpane",
name = "SplitPane for Compose JB"
)

0
components/SplitPane/common/src/commonMain/kotlin/org/jetbrains/compose/splitpane/ExperimentalSplitPaneApi.kt → components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/ExperimentalSplitPaneApi.kt

0
components/SplitPane/common/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPane.kt → components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPane.kt

0
components/SplitPane/common/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneDSL.kt → components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneDSL.kt

0
components/SplitPane/common/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt → components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt

0
components/SplitPane/common/src/commonMain/kotlin/org/jetbrains/compose/splitpane/Splitter.kt → components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/Splitter.kt

280
components/SplitPane/common/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitPane.kt → components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitPane.kt

@ -1,141 +1,141 @@
package org.jetbrains.compose.splitpane
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
import kotlin.math.roundToInt
private fun Constraints.maxByDirection(isHorizontal: Boolean): Int = if (isHorizontal) maxWidth else maxHeight
private fun Constraints.minByDirection(isHorizontal: Boolean): Int = if (isHorizontal) minWidth else minHeight
private fun Placeable.valueByDirection(isHorizontal: Boolean): Int = if (isHorizontal) width else height
@OptIn(ExperimentalSplitPaneApi::class)
@Composable
internal actual fun SplitPane(
modifier: Modifier,
isHorizontal: Boolean,
splitPaneState: SplitPaneState,
minimalSizesConfiguration: MinimalSizes,
first: @Composable () -> Unit,
second: @Composable () -> Unit,
splitter: Splitter
) {
Layout(
{
first()
splitter.measuredPart()
second()
splitter.handlePart()
},
modifier,
) { measurables, constraints ->
with(minimalSizesConfiguration) {
with(splitPaneState) {
val constrainedMin = constraints.minByDirection(isHorizontal) + firstPlaceableMinimalSize.value
val constrainedMax =
(constraints.maxByDirection(isHorizontal).toFloat() - secondPlaceableMinimalSize.value).let {
if (it <= 0 || it <= constrainedMin) {
constraints.maxByDirection(isHorizontal).toFloat()
} else {
it
}
}
if (minPosition != constrainedMin) {
maxPosition = constrainedMin
}
if (maxPosition != constrainedMax) {
maxPosition =
if ((firstPlaceableMinimalSize + secondPlaceableMinimalSize).value < constraints.maxByDirection(isHorizontal)) {
constrainedMax
} else {
minPosition
}
}
val constrainedPosition =
(constraints.maxByDirection(isHorizontal) - (firstPlaceableMinimalSize + secondPlaceableMinimalSize).value).let {
if (it > 0f) {
(it * positionPercentage).coerceIn(constrainedMin, constrainedMax).roundToInt()
} else {
constrainedMin.roundToInt()
}
}
val firstPlaceable = measurables[0].measure(
if (isHorizontal) {
constraints.copy(
minWidth = 0,
maxWidth = constrainedPosition
)
} else {
constraints.copy(
minHeight = 0,
maxHeight = constrainedPosition
)
}
)
val splitterPlaceable = measurables[1].measure(constraints)
val splitterSize = splitterPlaceable.valueByDirection(isHorizontal)
val secondPlaceablePosition = constrainedPosition + splitterSize
val secondPlaceableSize =
(constraints.maxByDirection(isHorizontal) - secondPlaceablePosition).coerceIn(
0,
if (secondPlaceablePosition < constraints.maxByDirection(isHorizontal)) {
constraints.maxByDirection(isHorizontal) - secondPlaceablePosition
} else {
constraints.maxByDirection(isHorizontal)
}
)
val secondPlaceable = measurables[2].measure(
if (isHorizontal) {
constraints.copy(
minWidth = 0,
maxWidth = secondPlaceableSize
)
} else {
constraints.copy(
minHeight = 0,
maxHeight = secondPlaceableSize
)
}
)
val handlePlaceable = measurables[3].measure(constraints)
val handleSize = handlePlaceable.valueByDirection(isHorizontal)
// TODO support RTL
val handlePosition = when (splitter.alignment) {
SplitterHandleAlignment.BEFORE -> constrainedPosition + splitterSize - handleSize
SplitterHandleAlignment.ABOVE -> constrainedPosition + (splitterSize - handleSize) / 2
SplitterHandleAlignment.AFTER -> constrainedPosition
}
layout(constraints.maxWidth, constraints.maxHeight) {
firstPlaceable.place(0, 0)
if (isHorizontal) {
secondPlaceable.place(secondPlaceablePosition, 0)
splitterPlaceable.place(constrainedPosition, 0)
if (moveEnabled) {
handlePlaceable.place(handlePosition, 0)
}
} else {
secondPlaceable.place(0, secondPlaceablePosition)
splitterPlaceable.place(0, constrainedPosition)
if (moveEnabled) {
handlePlaceable.place(0, handlePosition)
}
}
}
}
}
}
package org.jetbrains.compose.splitpane
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
import kotlin.math.roundToInt
private fun Constraints.maxByDirection(isHorizontal: Boolean): Int = if (isHorizontal) maxWidth else maxHeight
private fun Constraints.minByDirection(isHorizontal: Boolean): Int = if (isHorizontal) minWidth else minHeight
private fun Placeable.valueByDirection(isHorizontal: Boolean): Int = if (isHorizontal) width else height
@OptIn(ExperimentalSplitPaneApi::class)
@Composable
internal actual fun SplitPane(
modifier: Modifier,
isHorizontal: Boolean,
splitPaneState: SplitPaneState,
minimalSizesConfiguration: MinimalSizes,
first: @Composable () -> Unit,
second: @Composable () -> Unit,
splitter: Splitter
) {
Layout(
{
first()
splitter.measuredPart()
second()
splitter.handlePart()
},
modifier,
) { measurables, constraints ->
with(minimalSizesConfiguration) {
with(splitPaneState) {
val constrainedMin = constraints.minByDirection(isHorizontal) + firstPlaceableMinimalSize.value
val constrainedMax =
(constraints.maxByDirection(isHorizontal).toFloat() - secondPlaceableMinimalSize.value).let {
if (it <= 0 || it <= constrainedMin) {
constraints.maxByDirection(isHorizontal).toFloat()
} else {
it
}
}
if (minPosition != constrainedMin) {
maxPosition = constrainedMin
}
if (maxPosition != constrainedMax) {
maxPosition =
if ((firstPlaceableMinimalSize + secondPlaceableMinimalSize).value < constraints.maxByDirection(isHorizontal)) {
constrainedMax
} else {
minPosition
}
}
val constrainedPosition =
(constraints.maxByDirection(isHorizontal) - (firstPlaceableMinimalSize + secondPlaceableMinimalSize).value).let {
if (it > 0f) {
(it * positionPercentage).coerceIn(constrainedMin, constrainedMax).roundToInt()
} else {
constrainedMin.roundToInt()
}
}
val firstPlaceable = measurables[0].measure(
if (isHorizontal) {
constraints.copy(
minWidth = 0,
maxWidth = constrainedPosition
)
} else {
constraints.copy(
minHeight = 0,
maxHeight = constrainedPosition
)
}
)
val splitterPlaceable = measurables[1].measure(constraints)
val splitterSize = splitterPlaceable.valueByDirection(isHorizontal)
val secondPlaceablePosition = constrainedPosition + splitterSize
val secondPlaceableSize =
(constraints.maxByDirection(isHorizontal) - secondPlaceablePosition).coerceIn(
0,
if (secondPlaceablePosition < constraints.maxByDirection(isHorizontal)) {
constraints.maxByDirection(isHorizontal) - secondPlaceablePosition
} else {
constraints.maxByDirection(isHorizontal)
}
)
val secondPlaceable = measurables[2].measure(
if (isHorizontal) {
constraints.copy(
minWidth = 0,
maxWidth = secondPlaceableSize
)
} else {
constraints.copy(
minHeight = 0,
maxHeight = secondPlaceableSize
)
}
)
val handlePlaceable = measurables[3].measure(constraints)
val handleSize = handlePlaceable.valueByDirection(isHorizontal)
// TODO support RTL
val handlePosition = when (splitter.alignment) {
SplitterHandleAlignment.BEFORE -> constrainedPosition + splitterSize - handleSize
SplitterHandleAlignment.ABOVE -> constrainedPosition + (splitterSize - handleSize) / 2
SplitterHandleAlignment.AFTER -> constrainedPosition
}
layout(constraints.maxWidth, constraints.maxHeight) {
firstPlaceable.place(0, 0)
if (isHorizontal) {
secondPlaceable.place(secondPlaceablePosition, 0)
splitterPlaceable.place(constrainedPosition, 0)
if (moveEnabled) {
handlePlaceable.place(handlePosition, 0)
}
} else {
secondPlaceable.place(0, secondPlaceablePosition)
splitterPlaceable.place(0, constrainedPosition)
if (moveEnabled) {
handlePlaceable.place(0, handlePosition)
}
}
}
}
}
}
}

202
components/SplitPane/common/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitter.kt → components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitter.kt

@ -1,101 +1,101 @@
package org.jetbrains.compose.splitpane
import androidx.compose.desktop.LocalAppWindow
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material.MaterialTheme
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.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.consumeAllChanges
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.pointerMoveFilter
import androidx.compose.ui.unit.dp
import java.awt.Cursor
private fun Modifier.cursorForHorizontalResize(
isHorizontal: Boolean
): Modifier = composed {
var isHover by remember { mutableStateOf(false) }
if (isHover) {
LocalAppWindow.current.window.cursor = Cursor(
if (isHorizontal) Cursor.E_RESIZE_CURSOR else Cursor.S_RESIZE_CURSOR
)
} else {
LocalAppWindow.current.window.cursor = Cursor.getDefaultCursor()
}
pointerMoveFilter(
onEnter = { isHover = true; true },
onExit = { isHover = false; true }
)
}
@Composable
private fun DesktopSplitPaneSeparator(
isHorizontal: Boolean,
color: Color = MaterialTheme.colors.background
) = Box(
Modifier
.run {
if (isHorizontal) {
this.width(1.dp)
.fillMaxHeight()
} else {
this.height(1.dp)
.fillMaxWidth()
}
}
.background(color)
)
@OptIn(ExperimentalSplitPaneApi::class)
@Composable
private fun DesktopHandle(
isHorizontal: Boolean,
splitPaneState: SplitPaneState
) = Box(
Modifier
.pointerInput(splitPaneState) {
detectDragGestures { change, _ ->
change.consumeAllChanges()
splitPaneState.dispatchRawMovement(
if (isHorizontal) change.position.x else change.position.y
)
}
}
.cursorForHorizontalResize(isHorizontal)
.run {
if (isHorizontal) {
this.width(8.dp)
.fillMaxHeight()
} else {
this.height(8.dp)
.fillMaxWidth()
}
}
)
@OptIn(ExperimentalSplitPaneApi::class)
internal actual fun defaultSplitter(
isHorizontal: Boolean,
splitPaneState: SplitPaneState
): Splitter = Splitter(
measuredPart = {
DesktopSplitPaneSeparator(isHorizontal)
},
handlePart = {
DesktopHandle(isHorizontal, splitPaneState)
}
)
package org.jetbrains.compose.splitpane
import androidx.compose.desktop.LocalAppWindow
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material.MaterialTheme
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.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.consumeAllChanges
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.pointerMoveFilter
import androidx.compose.ui.unit.dp
import java.awt.Cursor
private fun Modifier.cursorForHorizontalResize(
isHorizontal: Boolean
): Modifier = composed {
var isHover by remember { mutableStateOf(false) }
if (isHover) {
LocalAppWindow.current.window.cursor = Cursor(
if (isHorizontal) Cursor.E_RESIZE_CURSOR else Cursor.S_RESIZE_CURSOR
)
} else {
LocalAppWindow.current.window.cursor = Cursor.getDefaultCursor()
}
pointerMoveFilter(
onEnter = { isHover = true; true },
onExit = { isHover = false; true }
)
}
@Composable
private fun DesktopSplitPaneSeparator(
isHorizontal: Boolean,
color: Color = MaterialTheme.colors.background
) = Box(
Modifier
.run {
if (isHorizontal) {
this.width(1.dp)
.fillMaxHeight()
} else {
this.height(1.dp)
.fillMaxWidth()
}
}
.background(color)
)
@OptIn(ExperimentalSplitPaneApi::class)
@Composable
private fun DesktopHandle(
isHorizontal: Boolean,
splitPaneState: SplitPaneState
) = Box(
Modifier
.pointerInput(splitPaneState) {
detectDragGestures { change, _ ->
change.consumeAllChanges()
splitPaneState.dispatchRawMovement(
if (isHorizontal) change.position.x else change.position.y
)
}
}
.cursorForHorizontalResize(isHorizontal)
.run {
if (isHorizontal) {
this.width(8.dp)
.fillMaxHeight()
} else {
this.height(8.dp)
.fillMaxWidth()
}
}
)
@OptIn(ExperimentalSplitPaneApi::class)
internal actual fun defaultSplitter(
isHorizontal: Boolean,
splitPaneState: SplitPaneState
): Splitter = Splitter(
measuredPart = {
DesktopSplitPaneSeparator(isHorizontal)
},
handlePart = {
DesktopHandle(isHorizontal, splitPaneState)
}
)

21
components/VideoPlayer/build.gradle.kts

@ -1,21 +0,0 @@
import org.jetbrains.compose.compose
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
jvm {
withJava()
}
sourceSets {
named("jvmMain") {
dependencies {
implementation(compose.desktop.currentOs)
implementation(project("common"))
}
}
}
}

2
components/VideoPlayer/desktop/build.gradle.kts → components/VideoPlayer/demo/build.gradle.kts

@ -11,7 +11,7 @@ kotlin {
named("jvmMain") {
dependencies {
implementation(compose.desktop.currentOs)
implementation(project(":VideoPlayer:common"))
implementation(project(":VideoPlayer:library"))
}
}
}

0
components/VideoPlayer/desktop/src/jvmMain/kotlin/org/jetbrains/compose/videoplayer/demo/Main.kt → components/VideoPlayer/demo/src/jvmMain/kotlin/org/jetbrains/compose/videoplayer/demo/Main.kt

0
components/VideoPlayer/common/build.gradle.kts → components/VideoPlayer/library/build.gradle.kts

0
components/VideoPlayer/common/src/commonMain/kotlin/org/jetbrains/compose/videoplayer/VideoPlayer.kt → components/VideoPlayer/library/src/commonMain/kotlin/org/jetbrains/compose/videoplayer/VideoPlayer.kt

0
components/VideoPlayer/common/src/desktopMain/kotlin/org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt → components/VideoPlayer/library/src/desktopMain/kotlin/org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt

34
components/build.gradle.kts

@ -1,6 +1,5 @@
buildscript {
// __LATEST_COMPOSE_RELEASE_VERSION__
val composeVersion = System.getenv("COMPOSE_RELEASE_VERSION") ?: "0.4.0"
val composeVersion = property("compose.version")
repositories {
google()
@ -15,10 +14,37 @@ buildscript {
}
}
allprojects {
subprojects {
version = findProperty("deploy.version") ?: property("compose.version")!!
repositories {
google()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
}
plugins.withId("java") {
configureIfExists<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
withJavadocJar()
withSourcesJar()
}
}
plugins.withId("maven-publish") {
configureIfExists<PublishingExtension> {
repositories {
maven {
name = "ComposeRepo"
setUrl(System.getenv("COMPOSE_REPO_URL"))
credentials {
username = System.getenv("COMPOSE_REPO_USERNAME")
password = System.getenv("COMPOSE_REPO_KEY")
}
}
}
}
}
}

11
components/buildSrc/build.gradle.kts

@ -0,0 +1,11 @@
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
}
dependencies {
compileOnly(gradleApi())
}

5
components/buildSrc/settings.gradle.kts

@ -0,0 +1,5 @@
pluginManagement {
repositories {
gradlePluginPortal()
}
}

32
components/buildSrc/src/main/kotlin/CommonMavenProperties.kt

@ -0,0 +1,32 @@
import org.gradle.api.Project
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.kotlin.dsl.configure
fun Project.configureMavenPublication(
groupId: String,
artifactId: String,
name: String
) {
extensions.configure<PublishingExtension> {
publications {
all {
this as MavenPublication
this.groupId = groupId
mppArtifactId = artifactId
pom {
this.name.set(name)
url.set("https://github.com/JetBrains/compose-jb")
licenses {
license {
this.name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
}
}
}
}
}

19
components/buildSrc/src/main/kotlin/GradleUtils.kt

@ -0,0 +1,19 @@
/*
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/
import org.gradle.api.Project
import org.gradle.api.publish.maven.MavenPublication
import java.lang.UnsupportedOperationException
inline fun <reified T> Project.configureIfExists(fn: T.() -> Unit) {
extensions.findByType(T::class.java)?.fn()
}
var MavenPublication.mppArtifactId: String
get() = throw UnsupportedOperationException()
set(value) {
val target = this.name
artifactId = if ("kotlinMultiplatform" in target) value else "$value-$target"
}

5
components/gradle.properties

@ -1,4 +1,7 @@
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
android.enableJetifier=true
kotlin.code.style=official
kotlin.code.style=official
# __LATEST_COMPOSE_RELEASE_VERSION__
compose.version=0.4.0

8
components/settings.gradle.kts

@ -1,4 +1,4 @@
include(":VideoPlayer:common")
include(":VideoPlayer:desktop")
include(":SplitPane:common")
include(":SplitPane:desktop")
include(":VideoPlayer:library")
include(":VideoPlayer:demo")
include(":SplitPane:library")
include(":SplitPane:demo")

6
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt

@ -123,6 +123,8 @@ class ComposePlugin : Plugin<Project> {
}
object DesktopDependencies {
val components = DesktopComponentsDependencies
val common = composeDependency("org.jetbrains.compose.desktop:desktop")
val linux_x64 = composeDependency("org.jetbrains.compose.desktop:desktop-jvm-linux-x64")
val windows_x64 = composeDependency("org.jetbrains.compose.desktop:desktop-jvm-windows-x64")
@ -150,6 +152,10 @@ class ComposePlugin : Plugin<Project> {
}
}
object DesktopComponentsDependencies {
val splitPane = composeDependency("org.jetbrains.compose.components:components-splitpane")
}
object WebDependencies {
val core by lazy {
composeDependency("org.jetbrains.compose.web:web-core")

Loading…
Cancel
Save