Tabs now can be scrolled with a scrollbar or shift+mouse wheel

This commit is contained in:
Abdelilah El Aissaoui 2022-10-19 23:16:22 +02:00
parent 325420bf47
commit fdbf92083a

View File

@ -1,15 +1,15 @@
@file:OptIn(ExperimentalComposeUiApi::class)
package com.jetpackduba.gitnuro.ui.components
import androidx.compose.foundation.HorizontalScrollbar
import androidx.compose.foundation.background
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.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollbarAdapter
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
@ -19,7 +19,6 @@ import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Close
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@ -32,12 +31,10 @@ import com.jetpackduba.gitnuro.di.DaggerTabComponent
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.preferences.AppSettings
import com.jetpackduba.gitnuro.viewmodels.DiffViewModel
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
import com.jetpackduba.gitnuro.viewmodels.TabViewModel
import com.jetpackduba.gitnuro.viewmodels.TabViewModelsHolder
import javax.inject.Inject
import javax.inject.Provider
import kotlin.io.path.Path
import kotlin.io.path.name
@ -51,17 +48,29 @@ fun RepositoriesTabPanel(
newTabContent: (key: Int) -> TabInformation,
) {
var tabsIdentifier by remember { mutableStateOf(tabs.count()) }
val stateHorizontal = rememberLazyListState()
TabPanel(
modifier = modifier,
onNewTabClicked = {
tabsIdentifier++
LaunchedEffect(selectedTabKey) {
val index = tabs.indexOfFirst { it.key == selectedTabKey }
newTabContent(tabsIdentifier)
onTabSelected(tabsIdentifier)
if (index > -1) {
stateHorizontal.scrollToItem(index)
}
}
Row {
Box(
modifier = Modifier
.weight(1f, false)
) {
items(items = tabs) { tab ->
LazyRow(
modifier = Modifier
.fillMaxHeight(),
state = stateHorizontal,
) {
items(items = tabs, key = { it.key }) { tab ->
Tab(
title = tab.tabName,
isSelected = tab.key == selectedTabKey,
@ -70,22 +79,10 @@ fun RepositoriesTabPanel(
},
onCloseTab = {
val isTabSelected = selectedTabKey == tab.key
val index = tabs.indexOf(tab)
val nextIndex = if (index == 0 && tabs.count() >= 2) {
1 // If the first tab is selected, select the next one
} else if (index == tabs.count() - 1 && tabs.count() >= 2)
index - 1 // If the last tab is selected, select the previous one
else if (tabs.count() >= 2)
index + 1 // If any in between tab is selected, select the next one
else
-1 // If there aren't any additional tabs once we remove this one
val nextKey = if (nextIndex >= 0)
tabs[nextIndex].key
else
-1
if (isTabSelected) {
val nextKey = getTabNextKey(tab, tabs)
if (nextKey >= 0) {
onTabSelected(nextKey)
} else {
@ -102,29 +99,30 @@ fun RepositoriesTabPanel(
)
}
}
}
@Composable
fun TabPanel(
modifier: Modifier = Modifier,
onNewTabClicked: () -> Unit,
tabs: LazyListScope.() -> Unit
) {
LazyRow(
modifier = modifier
.fillMaxHeight(),
Tooltip(
"\"Shift + Mouse wheel\" to scroll"
) {
this.tabs()
HorizontalScrollbar(
modifier = Modifier
.align(Alignment.TopStart)
.width((tabs.count() * 180).dp),
adapter = rememberScrollbarAdapter(stateHorizontal)
)
}
}
item {
Box(modifier = Modifier.fillMaxSize()) {
IconButton(
onClick = onNewTabClicked,
onClick = {
tabsIdentifier++
newTabContent(tabsIdentifier)
onTabSelected(tabsIdentifier)
},
modifier = Modifier
.size(36.dp)
.handOnHover()
.align(Alignment.CenterStart),
.align(Alignment.CenterVertically),
) {
Icon(
imageVector = Icons.Default.Add,
@ -133,8 +131,24 @@ fun TabPanel(
)
}
}
}
}
}
private fun getTabNextKey(tab: TabInformation, tabs: List<TabInformation>): Int {
val index = tabs.indexOf(tab)
val nextIndex = if (index == 0 && tabs.count() >= 2) {
1 // If the first tab is selected, select the next one
} else if (index == tabs.count() - 1 && tabs.count() >= 2)
index - 1 // If the last tab is selected, select the previous one
else if (tabs.count() >= 2)
index + 1 // If any in between tab is selected, select the next one
else
-1 // If there aren't any additional tabs once we remove this one
return if (nextIndex >= 0)
tabs[nextIndex].key
else
-1
}
@Composable