From 30fdf0d0032dc1ec7b69e85c035c97cefd6729f7 Mon Sep 17 00:00:00 2001 From: AmirHossein Abdolmotallebi Date: Thu, 17 Oct 2024 20:15:14 +0330 Subject: [PATCH] add file drag and drop to external app --- .../pages/home/DownloadItemListDataFlavor.kt | 47 +++++++++++++++++++ .../desktop/pages/home/HomePage.kt | 5 +- .../pages/home/sections/DownloadList.kt | 40 ++++++++++++++-- 3 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/DownloadItemListDataFlavor.kt diff --git a/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/DownloadItemListDataFlavor.kt b/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/DownloadItemListDataFlavor.kt new file mode 100644 index 0000000..6dfe631 --- /dev/null +++ b/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/DownloadItemListDataFlavor.kt @@ -0,0 +1,47 @@ +package com.abdownloadmanager.desktop.pages.home + +import ir.amirab.downloader.monitor.IDownloadItemState +import java.awt.datatransfer.DataFlavor +import java.awt.datatransfer.Transferable +import java.awt.datatransfer.UnsupportedFlavorException +import java.io.File + +val DownloadItemListDataFlavor = DataFlavor( + IDownloadItemState::class.java, + "Download Item" +) + +class DownloadItemTransferable( + val items: List, +) : Transferable { + override fun getTransferDataFlavors(): Array { + return arrayOf( + DataFlavor.javaFileListFlavor, + DataFlavor.stringFlavor, + DownloadItemListDataFlavor, + ) + } + + override fun isDataFlavorSupported(flavor: DataFlavor?): Boolean { + return (flavor in arrayOf( + DataFlavor.javaFileListFlavor, + DataFlavor.stringFlavor, + DownloadItemListDataFlavor, + )) + } + + override fun getTransferData(flavor: DataFlavor?): Any { + return when (flavor) { + DataFlavor.javaFileListFlavor -> items.map { + File(it.folder, it.name) + } + + DataFlavor.stringFlavor -> items.map { + it.downloadLink + }.joinToString("\n") + + DownloadItemListDataFlavor -> items + else -> throw UnsupportedFlavorException(flavor) + } + } +} \ No newline at end of file diff --git a/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/HomePage.kt b/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/HomePage.kt index 2c2b885..9464006 100644 --- a/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/HomePage.kt +++ b/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/HomePage.kt @@ -168,7 +168,10 @@ fun HomePage(component: HomeComponent) { .fillMaxSize() .dragAndDropTarget( shouldStartDragAndDrop = { - it.awtTransferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor) || + if (it.awtTransferable.isDataFlavorSupported(DownloadItemListDataFlavor)) { + // this item is ours we don't want to use our download item for import list usage + return@dragAndDropTarget false + } else it.awtTransferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor) || it.awtTransferable.isDataFlavorSupported(DataFlavor.stringFlavor) }, target = remember { diff --git a/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/sections/DownloadList.kt b/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/sections/DownloadList.kt index 197f43c..8dc3a5e 100644 --- a/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/sections/DownloadList.kt +++ b/desktop/app/src/main/kotlin/com/abdownloadmanager/desktop/pages/home/sections/DownloadList.kt @@ -13,6 +13,8 @@ import com.abdownloadmanager.desktop.ui.widget.menu.MenuDisabledItemBehavior import com.abdownloadmanager.desktop.ui.widget.menu.ShowOptionsInDropDown import ir.amirab.util.compose.action.MenuItem import androidx.compose.foundation.* +import androidx.compose.foundation.draganddrop.dragAndDropSource +import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.rememberLazyListState @@ -20,11 +22,15 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draganddrop.DragAndDropTransferAction +import androidx.compose.ui.draganddrop.DragAndDropTransferData +import androidx.compose.ui.draganddrop.DragAndDropTransferable import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.key.* import androidx.compose.ui.input.pointer.* import androidx.compose.ui.unit.dp +import com.abdownloadmanager.desktop.pages.home.DownloadItemTransferable import com.abdownloadmanager.utils.FileIconProvider import com.abdownloadmanager.utils.category.CategoryManager import com.abdownloadmanager.utils.category.rememberCategoryOf @@ -82,8 +88,12 @@ fun DownloadList( it in selectionList } } - } + + val listToBeDragged by rememberUpdatedState( + downloadList.filter { it.id in selectionList } + ) + val tableInteractionSource = remember { MutableInteractionSource() } fun newSelection(ids: List, isSelected: Boolean) { @@ -110,6 +120,31 @@ fun DownloadList( key = { it.id }, list = downloadList, modifier = modifier + .dragAndDropSource( + drawDragDecoration = { + }, + block = { + detectDragGestures( + onDrag = { _ -> + val selectedDownloads = listToBeDragged + if (selectedDownloads.isEmpty()) { + return@detectDragGestures + } + startTransfer( + DragAndDropTransferData( + transferable = DragAndDropTransferable( + DownloadItemTransferable(selectedDownloads) + ), + supportedActions = listOf( + // TODO it doesn't work! + DragAndDropTransferAction.Copy, + ), + ) + ) + } + ) + } + ) .onKeyEvent { val ctrlPressed = it.isCtrlPressed val shiftPressed = it.isShiftPressed @@ -366,5 +401,4 @@ fun ShowDownloadOptions( } } -} - +} \ No newline at end of file