diff --git a/build.gradle.kts b/build.gradle.kts index 455fb24..25dd88d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,6 +24,8 @@ repositories { dependencies { implementation(compose.desktop.currentOs) + @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) + implementation(compose.desktop.components.splitPane) implementation("org.eclipse.jgit:org.eclipse.jgit:5.13.0.202109080827-r") implementation("org.apache.sshd:sshd-core:2.7.0") implementation("com.google.dagger:dagger:2.39.1") diff --git a/src/main/kotlin/app/ui/RepositoryOpen.kt b/src/main/kotlin/app/ui/RepositoryOpen.kt index 18f2c4d..b4ab21f 100644 --- a/src/main/kotlin/app/ui/RepositoryOpen.kt +++ b/src/main/kotlin/app/ui/RepositoryOpen.kt @@ -1,10 +1,17 @@ package app.ui import androidx.compose.animation.Crossfade +import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.input.pointer.PointerIcon +import androidx.compose.ui.input.pointer.PointerIconDefaults +import androidx.compose.ui.input.pointer.pointerHoverIcon import androidx.compose.ui.unit.dp import app.DialogManager import app.credentials.CredentialsState @@ -15,8 +22,13 @@ import app.ui.dialogs.PasswordDialog import app.ui.dialogs.UserPasswordDialog import openRepositoryDialog import org.eclipse.jgit.revwalk.RevCommit +import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi +import org.jetbrains.compose.splitpane.HorizontalSplitPane +import org.jetbrains.compose.splitpane.rememberSplitPaneState +import java.awt.Cursor +@OptIn(ExperimentalSplitPaneApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class) @Composable fun RepositoryOpenPage(gitManager: GitManager, dialogManager: DialogManager) { var selectedRevCommit by remember { @@ -87,76 +99,128 @@ fun RepositoryOpenPage(gitManager: GitManager, dialogManager: DialogManager) { ) Row { - Column( - modifier = Modifier - .widthIn(min = 300.dp) - .weight(0.15f) - .fillMaxHeight() - ) { - Branches(gitManager = gitManager) - Tags(gitManager = gitManager) - Stashes(gitManager = gitManager) - } - Box( - modifier = Modifier - .weight(0.60f) - .fillMaxHeight() - ) { - Crossfade(targetState = diffSelected) { diffEntry -> - when (diffEntry) { - null -> { - Log( - gitManager = gitManager, - dialogManager = dialogManager, - selectedIndex = selectedIndexCommitLog, - onRevCommitSelected = { commit -> - selectedRevCommit = commit - uncommitedChangesSelected = false - }, - onUncommitedChangesSelected = { - gitManager.statusShouldBeUpdated() - uncommitedChangesSelected = true - }, - ) - } - else -> { - Diff( - gitManager = gitManager, - diffEntryType = diffEntry, - onCloseDiffView = { diffSelected = null }) - } + HorizontalSplitPane() { + first(minSize = 200.dp) { + Column( + modifier = Modifier + .widthIn(min = 300.dp) + .weight(0.15f) + .fillMaxHeight() + ) { + Branches(gitManager = gitManager) + Tags(gitManager = gitManager) + Stashes(gitManager = gitManager) } } - } - Box( - modifier = Modifier - .weight(0.25f) - .fillMaxHeight() - ) { - if (uncommitedChangesSelected) { - UncommitedChanges( - gitManager = gitManager, - onStagedDiffEntrySelected = { diffEntry -> - diffSelected = if (diffEntry != null) - DiffEntryType.StagedDiff(diffEntry) - else - null - }, - onUnstagedDiffEntrySelected = { diffEntry -> - diffSelected = DiffEntryType.UnstagedDiff(diffEntry) - } - ) - } else { - selectedRevCommit?.let { - CommitChanges( - gitManager = gitManager, - commit = it, - onDiffSelected = { diffEntry -> - diffSelected = DiffEntryType.CommitDiff(diffEntry) - } + splitter { + visiblePart { + Box( + Modifier + .width(1.dp) + .fillMaxHeight() + .background(MaterialTheme.colors.background) ) } + handle { + Box( + Modifier + .markAsHandle() + .background(SolidColor(Color.Gray), alpha = 0.50f) + .width(2.dp) + .pointerHoverIcon(PointerIcon(Cursor(Cursor.E_RESIZE_CURSOR))) + .fillMaxHeight() + ) + } + } + second { + HorizontalSplitPane( + splitPaneState = rememberSplitPaneState(0.9f) + ) { + first() { + Box( + modifier = Modifier + .fillMaxSize() + ) { + Crossfade(targetState = diffSelected) { diffEntry -> + when (diffEntry) { + null -> { + Log( + gitManager = gitManager, + dialogManager = dialogManager, + selectedIndex = selectedIndexCommitLog, + onRevCommitSelected = { commit -> + selectedRevCommit = commit + uncommitedChangesSelected = false + }, + onUncommitedChangesSelected = { + gitManager.statusShouldBeUpdated() + uncommitedChangesSelected = true + }, + ) + } + else -> { + Diff( + gitManager = gitManager, + diffEntryType = diffEntry, + onCloseDiffView = { diffSelected = null }) + } + } + } + } + } + splitter { + visiblePart { + Box( + Modifier + .width(1.dp) + .fillMaxHeight() + .background(MaterialTheme.colors.background) + ) + } + handle { + Box( + Modifier + .markAsHandle() + .background(SolidColor(Color.Gray), alpha = 0.50f) + .width(2.dp) + .pointerHoverIcon(PointerIcon(Cursor(Cursor.E_RESIZE_CURSOR))) + .fillMaxHeight() + ) + } + } + second(minSize = 300.dp) { + Box( + modifier = Modifier + .fillMaxHeight() + ) { + if (uncommitedChangesSelected) { + UncommitedChanges( + gitManager = gitManager, + onStagedDiffEntrySelected = { diffEntry -> + diffSelected = if (diffEntry != null) + DiffEntryType.StagedDiff(diffEntry) + else + null + }, + onUnstagedDiffEntrySelected = { diffEntry -> + diffSelected = DiffEntryType.UnstagedDiff(diffEntry) + } + ) + } else { + selectedRevCommit?.let { + CommitChanges( + gitManager = gitManager, + commit = it, + onDiffSelected = { diffEntry -> + diffSelected = DiffEntryType.CommitDiff(diffEntry) + } + ) + } + } + } + } + } } } }