diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/App.kt b/src/main/kotlin/com/jetpackduba/gitnuro/App.kt index f715e7f..ca91d5e 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/App.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/App.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier +import androidx.compose.ui.input.key.onPreviewKeyEvent import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.Density @@ -25,6 +26,8 @@ import com.jetpackduba.gitnuro.di.DaggerAppComponent import com.jetpackduba.gitnuro.extensions.preferenceValue import com.jetpackduba.gitnuro.extensions.toWindowPlacement import com.jetpackduba.gitnuro.git.AppGpgSigner +import com.jetpackduba.gitnuro.keybindings.KeybindingOption +import com.jetpackduba.gitnuro.keybindings.matchesBinding import com.jetpackduba.gitnuro.logging.printError import com.jetpackduba.gitnuro.managers.AppStateManager import com.jetpackduba.gitnuro.managers.TempFilesManager @@ -271,7 +274,38 @@ class App { if (currentTab != null) { Column( - modifier = Modifier.background(MaterialTheme.colors.background) + modifier = Modifier + .background(MaterialTheme.colors.background) + .onPreviewKeyEvent { + when { + it.matchesBinding(KeybindingOption.OPEN_NEW_TAB) -> { + tabsManager.addNewEmptyTab() + true + } + + it.matchesBinding(KeybindingOption.CLOSE_CURRENT_TAB) -> { + tabsManager.closeTab(currentTab) + true + } + + it.matchesBinding(KeybindingOption.CHANGE_CURRENT_TAB_LEFT) -> { + val tabToSelect = tabs.getOrNull(tabs.indexOf(currentTab) - 1) + if (tabToSelect != null) { + tabsManager.selectTab(tabToSelect) + } + true + } + + it.matchesBinding(KeybindingOption.CHANGE_CURRENT_TAB_RIGHT) -> { + val tabToSelect = tabs.getOrNull(tabs.indexOf(currentTab) + 1) + if (tabToSelect != null) { + tabsManager.selectTab(tabToSelect) + } + true + } + else -> false + } + } ) { Tabs( tabsInformationList = tabs, diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt b/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt index 672d335..97b5253 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt @@ -72,6 +72,26 @@ enum class KeybindingOption { * Used to pop stash changes to workspace */ OPEN_ANOTHER_REPOSITORY, + + /** + * Used to open a new tab + */ + OPEN_NEW_TAB, + + /** + * Used to close current tab + */ + CLOSE_CURRENT_TAB, + + /** + * Used to change current tab to the one in the left + */ + CHANGE_CURRENT_TAB_LEFT, + + /** + * Used to change current tab to the one in the right + */ + CHANGE_CURRENT_TAB_RIGHT, } @@ -114,6 +134,18 @@ private fun baseKeybindings() = mapOf( KeybindingOption.OPEN_ANOTHER_REPOSITORY to listOf( Keybinding(key = Key.O, control = true), ), + KeybindingOption.OPEN_NEW_TAB to listOf( + Keybinding(key = Key.T, control = true), + ), + KeybindingOption.CLOSE_CURRENT_TAB to listOf( + Keybinding(key = Key.W, control = true), + ), + KeybindingOption.CHANGE_CURRENT_TAB_LEFT to listOf( + Keybinding(key = Key.DirectionLeft, alt = true), + ), + KeybindingOption.CHANGE_CURRENT_TAB_RIGHT to listOf( + Keybinding(key = Key.DirectionRight, alt = true), + ), ) private fun linuxKeybindings(): Map> = baseKeybindings() diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt index 8b9e9b4..f2fffb5 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt @@ -22,6 +22,7 @@ import com.jetpackduba.gitnuro.keybindings.KeybindingOption import com.jetpackduba.gitnuro.keybindings.matchesBinding import com.jetpackduba.gitnuro.models.AuthorInfoSimple import com.jetpackduba.gitnuro.ui.components.SecondaryButton +import com.jetpackduba.gitnuro.ui.components.TabInformation import com.jetpackduba.gitnuro.ui.components.TripleVerticalSplitPanel import com.jetpackduba.gitnuro.ui.dialogs.* import com.jetpackduba.gitnuro.ui.diff.Diff diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/WelcomePage.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/WelcomePage.kt index 08ada0a..70e7e8b 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/WelcomePage.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/WelcomePage.kt @@ -25,7 +25,9 @@ import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.input.key.* +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow @@ -119,10 +121,12 @@ fun WelcomeView( ) { var showAdditionalInfo by remember { mutableStateOf(false) } + val searchFocusRequester = remember { FocusRequester() } Column( modifier = Modifier .fillMaxSize() + .focusable(true) .background(MaterialTheme.colors.surface), ) { @@ -156,6 +160,7 @@ fun WelcomeView( canRepositoriesBeRemoved = true, onOpenKnownRepository = onOpenKnownRepository, onRemoveRepositoryFromRecent = onRemoveRepositoryFromRecent, + searchFieldFocusRequester = searchFocusRequester, ) } } @@ -173,6 +178,10 @@ fun WelcomeView( ) } + LaunchedEffect(Unit) { + searchFocusRequester.requestFocus() + } + if (showAdditionalInfo) { AppInfoDialog( onClose = { showAdditionalInfo = false }, @@ -287,6 +296,7 @@ fun RecentRepositories( canRepositoriesBeRemoved: Boolean, onRemoveRepositoryFromRecent: (String) -> Unit, onOpenKnownRepository: (String) -> Unit, + searchFieldFocusRequester: FocusRequester, ) { Column( modifier = Modifier @@ -307,6 +317,7 @@ fun RecentRepositories( canRepositoriesBeRemoved = canRepositoriesBeRemoved, onRemoveRepositoryFromRecent = onRemoveRepositoryFromRecent, onOpenKnownRepository = onOpenKnownRepository, + searchFieldFocusRequester = searchFieldFocusRequester, ) } } @@ -316,7 +327,7 @@ fun RecentRepositories( fun RecentRepositoriesList( recentlyOpenedRepositories: List, canRepositoriesBeRemoved: Boolean, - searchFieldFocusRequester: FocusRequester = remember { FocusRequester() }, + searchFieldFocusRequester: FocusRequester, onRemoveRepositoryFromRecent: (String) -> Unit, onOpenKnownRepository: (String) -> Unit, ) { @@ -346,7 +357,7 @@ fun RecentRepositoriesList( return@onPreviewKeyEvent false } - when { + when { it.matchesBinding(KeybindingOption.DOWN) -> { if (focusedItemIndex < filteredRepositories.lastIndex) { focusedItemIndex += 1 diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt index 5e949f2..91a2608 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt @@ -21,7 +21,6 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.jetpackduba.gitnuro.AppIcons import com.jetpackduba.gitnuro.di.AppComponent