commonMain.androidx.compose.foundation.content.ReceiveContent.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of foundation-desktop Show documentation
Show all versions of foundation-desktop Show documentation
Higher level abstractions of the Compose UI primitives. This library is design system agnostic, providing the high-level building blocks for both application and design-system developers
The newest version!
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.foundation.content
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.content.internal.DynamicReceiveContentConfiguration
import androidx.compose.foundation.content.internal.ModifierLocalReceiveContent
import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
import androidx.compose.foundation.content.internal.ReceiveContentDragAndDropNode
import androidx.compose.foundation.content.internal.dragAndDropRequestPermission
import androidx.compose.ui.Modifier
import androidx.compose.ui.modifier.ModifierLocalMap
import androidx.compose.ui.modifier.ModifierLocalModifierNode
import androidx.compose.ui.modifier.modifierLocalMapOf
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.DelegatingNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.InspectorInfo
/**
* Configures the current node and any children nodes as a Content Receiver.
*
* Content in this context refers to a [TransferableContent] that could be received from another app
* through Drag-and-Drop, Copy/Paste, or from the Software Keyboard.
*
* There is no pre-filtering for the received content by media type, e.g. software Keyboard would
* assume that the app can handle any content that's sent to it. Therefore, it's crucial to check
* the received content's type and other related information before reading and processing it.
* Please refer to [TransferableContent.hasMediaType] and [TransferableContent.clipMetadata] to
* learn more about how to do proper checks on the received item.
*
* @param receiveContentListener Listener to respond to the receive event. This interface also
* includes a set of callbacks for certain Drag-and-Drop state changes. Please checkout
* [ReceiveContentListener] docs for an explanation of each callback.
* @sample androidx.compose.foundation.samples.ReceiveContentFullSample
* @see TransferableContent
* @see hasMediaType
*/
@Suppress("ExecutorRegistration")
@ExperimentalFoundationApi
fun Modifier.contentReceiver(receiveContentListener: ReceiveContentListener): Modifier {
// TODO https://youtrack.jetbrains.com/issue/COMPOSE-1263/Implement-Modifier.receiveContent
println("Modifier.receiveContent isn't supported in Compose Multiplatform yet")
return then(ReceiveContentElement(receiveContentListener = receiveContentListener))
}
@OptIn(ExperimentalFoundationApi::class)
internal data class ReceiveContentElement(val receiveContentListener: ReceiveContentListener) :
ModifierNodeElement() {
override fun create(): ReceiveContentNode {
return ReceiveContentNode(receiveContentListener)
}
override fun update(node: ReceiveContentNode) {
node.updateNode(receiveContentListener)
}
override fun InspectorInfo.inspectableProperties() {
name = "receiveContent"
}
}
// This node uses ModifierLocals instead of TraversableNode to find ancestor due to b/311181532.
// Since the usage of modifier locals are minimal and exactly correspond to how we would use
// TraversableNode if it was available, the switch should be fairly easy when the bug is fixed.
@OptIn(ExperimentalFoundationApi::class)
internal class ReceiveContentNode(var receiveContentListener: ReceiveContentListener) :
DelegatingNode(), ModifierLocalModifierNode, CompositionLocalConsumerModifierNode {
private val receiveContentConfiguration: ReceiveContentConfiguration =
DynamicReceiveContentConfiguration(this)
// The default provided configuration is the one supplied to this node. Once the node is
// attached, it should provide a delegating version to ancestor nodes.
override val providedValues: ModifierLocalMap =
modifierLocalMapOf(ModifierLocalReceiveContent to receiveContentConfiguration)
init {
delegate(
ReceiveContentDragAndDropNode(
receiveContentConfiguration = receiveContentConfiguration,
dragAndDropRequestPermission = { dragAndDropRequestPermission(it) }
)
)
}
fun updateNode(receiveContentListener: ReceiveContentListener) {
this.receiveContentListener = receiveContentListener
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy