Gitnuro/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/FileEntry.kt
2024-03-01 15:21:12 +01:00

162 lines
5.5 KiB
Kotlin

package com.jetpackduba.gitnuro.ui.components
import androidx.compose.foundation.hoverable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.foundation.layout.*
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.jetpackduba.gitnuro.AppIcons
import com.jetpackduba.gitnuro.extensions.backgroundIf
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.onDoubleClick
import com.jetpackduba.gitnuro.theme.backgroundSelected
import com.jetpackduba.gitnuro.theme.onBackgroundSecondary
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenuElement
private const val TREE_START_PADDING = 12
@Composable
fun FileEntry(
icon: ImageVector,
iconColor: Color,
parentDirectoryPath: String,
fileName: String,
isSelected: Boolean,
onClick: () -> Unit,
onDoubleClick: () -> Unit,
depth: Int = 0,
onGenerateContextMenu: () -> List<ContextMenuElement>,
trailingAction: (@Composable BoxScope.(isHovered: Boolean) -> Unit)?,
) {
FileEntry(
icon = rememberVectorPainter(icon),
iconColor = iconColor,
parentDirectoryPath = parentDirectoryPath,
fileName = fileName,
isSelected = isSelected,
onClick = onClick,
onDoubleClick = onDoubleClick,
depth = depth,
onGenerateContextMenu = onGenerateContextMenu,
trailingAction = trailingAction
)
}
@Composable
fun FileEntry(
icon: Painter,
iconColor: Color,
parentDirectoryPath: String,
fileName: String,
isSelected: Boolean,
onClick: () -> Unit,
onDoubleClick: () -> Unit,
depth: Int = 0,
onGenerateContextMenu: () -> List<ContextMenuElement>,
trailingAction: (@Composable BoxScope.(isHovered: Boolean) -> Unit)?,
) {
val hoverInteraction = remember { MutableInteractionSource() }
val isHovered by hoverInteraction.collectIsHoveredAsState()
Box(
modifier = Modifier
.handMouseClickable { onClick() }
.onDoubleClick(onDoubleClick)
.fillMaxWidth()
.hoverable(hoverInteraction)
) {
ContextMenu(
items = {
onGenerateContextMenu()
},
) {
Row(
modifier = Modifier
.height(40.dp)
.fillMaxWidth()
.backgroundIf(isSelected, MaterialTheme.colors.backgroundSelected)
.padding(start = (TREE_START_PADDING * depth).dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
painter = icon,
contentDescription = null,
modifier = Modifier
.padding(horizontal = 8.dp)
.size(16.dp),
tint = iconColor,
)
if (parentDirectoryPath.isNotEmpty()) {
Text(
text = parentDirectoryPath.removeSuffix("/"),
modifier = Modifier.weight(1f, fill = false),
maxLines = 1,
softWrap = false,
style = MaterialTheme.typography.body2,
overflow = TextOverflow.Ellipsis,
color = MaterialTheme.colors.onBackgroundSecondary,
)
Text(
text = "/",
maxLines = 1,
softWrap = false,
style = MaterialTheme.typography.body2,
overflow = TextOverflow.Visible,
color = MaterialTheme.colors.onBackgroundSecondary,
)
}
Text(
text = fileName,
maxLines = 1,
softWrap = false,
modifier = Modifier.padding(end = 16.dp),
style = MaterialTheme.typography.body2,
color = MaterialTheme.colors.onBackground,
)
}
}
trailingAction?.invoke(this, isHovered)
}
}
@Composable
fun DirectoryEntry(
dirName: String,
isExpanded: Boolean,
depth: Int = 0,
onClick: () -> Unit,
onGenerateContextMenu: () -> List<ContextMenuElement>,
) {
FileEntry(
icon = painterResource(if (isExpanded) AppIcons.FOLDER_OPEN else AppIcons.FOLDER),
iconColor = MaterialTheme.colors.onBackground,
isSelected = false,
onClick = onClick,
onDoubleClick = {},
parentDirectoryPath = "",
fileName = dirName,
depth = depth,
onGenerateContextMenu = onGenerateContextMenu,
trailingAction = null,
)
}