diff --git a/src/main/kotlin/main.kt b/src/main/kotlin/main.kt index 7144765..b54414a 100644 --- a/src/main/kotlin/main.kt +++ b/src/main/kotlin/main.kt @@ -1,28 +1,14 @@ import androidx.compose.animation.Crossfade -import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* -import androidx.compose.material.icons.Icons -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.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.input.pointer.pointerMoveFilter -import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.window.* import androidx.compose.ui.zIndex import git.GitManager @@ -32,7 +18,6 @@ import ui.RepositoryOpenPage import ui.WelcomePage import ui.components.RepositoriesTabPanel import ui.components.TabInformation -import javax.swing.JFileChooser @OptIn(ExperimentalComposeUiApi::class) fun main() = application { @@ -127,23 +112,12 @@ fun Gitnuro(isNewTab: Boolean, tabName: MutableState) { .background(MaterialTheme.colors.background) .fillMaxSize() ) { - GMenu( - onRepositoryOpen = { - openRepositoryDialog(gitManager = gitManager) - }, - onPull = { gitManager.pull() }, - onPush = { gitManager.push() }, - onStash = { gitManager.stash() }, - onPopStash = { gitManager.popStash() }, - isRepositoryOpen = repositorySelectionStatus is RepositorySelectionStatus.Open - ) - Crossfade(targetState = repositorySelectionStatus) { @Suppress("UnnecessaryVariable") // Don't inline it because smart cast won't work when (repositorySelectionStatus) { RepositorySelectionStatus.None -> { - WelcomePage() + WelcomePage(gitManager = gitManager) } RepositorySelectionStatus.Loading -> { LoadingRepository() @@ -162,122 +136,4 @@ fun Gitnuro(isNewTab: Boolean, tabName: MutableState) { fun LoadingRepository() { Box { } -} - - -@Composable -fun GMenu( - onRepositoryOpen: () -> Unit, - isRepositoryOpen: Boolean, - onPull: () -> Unit, - onPush: () -> Unit, - onStash: () -> Unit, - onPopStash: () -> Unit, -) { - val openHovering = remember { mutableStateOf(false) } - val pullHovering = remember { mutableStateOf(false) } - - Row( - modifier = Modifier - .padding(vertical = 16.dp) - .fillMaxWidth(), - horizontalArrangement = Arrangement.Center, - ) { - MenuButton( - title = "Open", - hovering = openHovering, - icon = painterResource("open.svg"), - onClick = { - openHovering.value = false // Without this, the hover would be kept because of the newly opened dialog - onRepositoryOpen() - } - ) - MenuButton( - title = "Pull", - hovering = pullHovering, - icon = painterResource("download.svg"), - onClick = { - pullHovering.value = false - onPull() - }, - enabled = isRepositoryOpen, - ) - MenuButton( - title = "Push", - icon = painterResource("upload.svg"), - onClick = onPush, - enabled = isRepositoryOpen, - ) - MenuButton( - title = "Stash", - icon = painterResource("stash.svg"), - onClick = onStash, - enabled = isRepositoryOpen, - ) - MenuButton( - title = "Apply", - icon = painterResource("apply_stash.svg"), - onClick = onPopStash, - enabled = isRepositoryOpen, - ) - } -} - -@Composable -fun MenuButton( - modifier: Modifier = Modifier, - enabled: Boolean = true, - hovering: MutableState = remember { mutableStateOf(false) }, - title: String, - icon: Painter, - onClick: () -> Unit -) { - val backgroundColor = if (hovering.value) - MaterialTheme.colors.primary.copy(alpha = 0.15F) - else - Color.Transparent - - val iconColor = if (enabled) { - MaterialTheme.colors.primary - } else { - MaterialTheme.colors.secondaryVariant - } - - TextButton( - modifier = modifier - .padding(horizontal = 2.dp) - .pointerMoveFilter( - onEnter = { - hovering.value = true - false - }, - onExit = { - hovering.value = false - false - } - ), - enabled = enabled, - onClick = onClick, - colors = ButtonDefaults.buttonColors( - backgroundColor = backgroundColor, - disabledBackgroundColor = Color.Transparent - ) - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Image( - painter = icon, - contentDescription = title, - modifier = Modifier - .padding(4.dp) - .size(24.dp), - colorFilter = ColorFilter.tint(iconColor), - ) - Text( - text = title, - fontSize = 12.sp, - color = MaterialTheme.colors.primaryTextColor - ) - } - - } -} +} \ No newline at end of file diff --git a/src/main/kotlin/ui/GMenu.kt b/src/main/kotlin/ui/GMenu.kt new file mode 100644 index 0000000..53b1b0c --- /dev/null +++ b/src/main/kotlin/ui/GMenu.kt @@ -0,0 +1,134 @@ +package ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.* +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +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.ColorFilter +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.input.pointer.pointerMoveFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import theme.primaryTextColor + +@Composable +fun GMenu( + onRepositoryOpen: () -> Unit, + onPull: () -> Unit, + onPush: () -> Unit, + onStash: () -> Unit, + onPopStash: () -> Unit, +) { + val openHovering = remember { mutableStateOf(false) } + val pullHovering = remember { mutableStateOf(false) } + + Row( + modifier = Modifier + .padding(vertical = 16.dp) + .fillMaxWidth(), + horizontalArrangement = Arrangement.Center, + ) { + MenuButton( + title = "Open", + hovering = openHovering, + icon = painterResource("open.svg"), + onClick = { + openHovering.value = false // Without this, the hover would be kept because of the newly opened dialog + onRepositoryOpen() + } + ) + MenuButton( + title = "Pull", + hovering = pullHovering, + icon = painterResource("download.svg"), + onClick = { + pullHovering.value = false + onPull() + }, + ) + MenuButton( + title = "Push", + icon = painterResource("upload.svg"), + onClick = onPush, + ) + MenuButton( + title = "Stash", + icon = painterResource("stash.svg"), + onClick = onStash, + ) + MenuButton( + title = "Apply", + icon = painterResource("apply_stash.svg"), + onClick = onPopStash, + ) + } +} + +@Composable +fun MenuButton( + modifier: Modifier = Modifier, + enabled: Boolean = true, + hovering: MutableState = remember { mutableStateOf(false) }, + title: String, + icon: Painter, + onClick: () -> Unit +) { + val backgroundColor = if (hovering.value) + MaterialTheme.colors.primary.copy(alpha = 0.15F) + else + Color.Transparent + + val iconColor = if (enabled) { + MaterialTheme.colors.primary + } else { + MaterialTheme.colors.secondaryVariant + } + + TextButton( + modifier = modifier + .padding(horizontal = 2.dp) + .pointerMoveFilter( + onEnter = { + hovering.value = true + false + }, + onExit = { + hovering.value = false + false + } + ), + enabled = enabled, + onClick = onClick, + colors = ButtonDefaults.buttonColors( + backgroundColor = backgroundColor, + disabledBackgroundColor = Color.Transparent + ) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Image( + painter = icon, + contentDescription = title, + modifier = Modifier + .padding(4.dp) + .size(24.dp), + colorFilter = ColorFilter.tint(iconColor), + ) + Text( + text = title, + fontSize = 12.sp, + color = MaterialTheme.colors.primaryTextColor + ) + } + + } +} diff --git a/src/main/kotlin/ui/RepositoryOpen.kt b/src/main/kotlin/ui/RepositoryOpen.kt index d314756..c8cd2d7 100644 --- a/src/main/kotlin/ui/RepositoryOpen.kt +++ b/src/main/kotlin/ui/RepositoryOpen.kt @@ -14,6 +14,8 @@ import androidx.compose.ui.window.Dialog import credentials.CredentialsState import git.DiffEntryType import git.GitManager +import git.RepositorySelectionStatus +import openRepositoryDialog import org.eclipse.jgit.revwalk.RevCommit @@ -79,76 +81,87 @@ fun RepositoryOpenPage(gitManager: GitManager) { - Row { - Column( - modifier = Modifier - .widthIn(min = 300.dp) - .weight(0.15f) - .fillMaxHeight() - ) { - Branches(gitManager = gitManager) - Stashes(gitManager = gitManager) - } - Box( - modifier = Modifier - .weight(0.60f) - .fillMaxHeight() - ) { - Crossfade(targetState = diffSelected) { diffEntry -> - when (diffEntry) { - null -> { - Log( - gitManager = gitManager, - selectedIndex = selectedIndexCommitLog, - onRevCommitSelected = { commit -> - // TODO Move all this code to tree manager + Column { + GMenu( + onRepositoryOpen = { + openRepositoryDialog(gitManager = gitManager) + }, + onPull = { gitManager.pull() }, + onPush = { gitManager.push() }, + onStash = { gitManager.stash() }, + onPopStash = { gitManager.popStash() }, + ) - selectedRevCommit = commit - uncommitedChangesSelected = false - }, - onUncommitedChangesSelected = { - gitManager.statusShouldBeUpdated() - uncommitedChangesSelected = true + Row { + Column( + modifier = Modifier + .widthIn(min = 300.dp) + .weight(0.15f) + .fillMaxHeight() + ) { + Branches(gitManager = gitManager) + Stashes(gitManager = gitManager) + } + Box( + modifier = Modifier + .weight(0.60f) + .fillMaxHeight() + ) { + Crossfade(targetState = diffSelected) { diffEntry -> + when (diffEntry) { + null -> { + Log( + gitManager = gitManager, + selectedIndex = selectedIndexCommitLog, + onRevCommitSelected = { commit -> + // TODO Move all this code to tree manager + + selectedRevCommit = commit + uncommitedChangesSelected = false + }, + onUncommitedChangesSelected = { + gitManager.statusShouldBeUpdated() + uncommitedChangesSelected = true + } + ) + } + else -> { + Diff( + gitManager = gitManager, + diffEntryType = diffEntry, + onCloseDiffView = { diffSelected = null }) + } + } + } + + } + Box( + modifier = Modifier + .weight(0.25f) + .fillMaxHeight() + ) { + if (uncommitedChangesSelected) { + UncommitedChanges( + gitManager = gitManager, + onStagedDiffEntrySelected = { diffEntry -> + diffSelected = DiffEntryType.StagedDiff(diffEntry) + }, + onUnstagedDiffEntrySelected = { diffEntry -> + diffSelected = DiffEntryType.UnstagedDiff(diffEntry) + } + ) + } else { + selectedRevCommit?.let { + CommitChanges( + gitManager = gitManager, + commit = it, + onDiffSelected = { diffEntry -> + diffSelected = DiffEntryType.CommitDiff(diffEntry) } ) } - else -> { - Diff( - gitManager = gitManager, - diffEntryType = diffEntry, - onCloseDiffView = { diffSelected = null }) - } - } - } - - } - Box( - modifier = Modifier - .weight(0.25f) - .fillMaxHeight() - ) { - if (uncommitedChangesSelected) { - UncommitedChanges( - gitManager = gitManager, - onStagedDiffEntrySelected = { diffEntry -> - diffSelected = DiffEntryType.StagedDiff(diffEntry) - }, - onUnstagedDiffEntrySelected = { diffEntry -> - diffSelected = DiffEntryType.UnstagedDiff(diffEntry) - } - ) - } else { - selectedRevCommit?.let { - CommitChanges( - gitManager = gitManager, - commit = it, - onDiffSelected = { diffEntry -> - diffSelected = DiffEntryType.CommitDiff(diffEntry) - } - ) } } } } } - diff --git a/src/main/kotlin/ui/WelcomePage.kt b/src/main/kotlin/ui/WelcomePage.kt index cd15e13..8f0e440 100644 --- a/src/main/kotlin/ui/WelcomePage.kt +++ b/src/main/kotlin/ui/WelcomePage.kt @@ -1,17 +1,23 @@ package ui import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import git.GitManager +import openRepositoryDialog @Composable -fun WelcomePage() { +fun WelcomePage(gitManager: GitManager) { Row( modifier = Modifier .fillMaxSize(), @@ -22,38 +28,42 @@ fun WelcomePage() { .fillMaxHeight(), verticalArrangement = Arrangement.Center, ) { - Button(onClick = {}) { - Image( - painter = painterResource("open.svg"), - contentDescription = null, - colorFilter = ColorFilter.tint(contentColorFor(MaterialTheme.colors.primary)) + ButtonTile( + title = "Open repository", + painter = painterResource("open.svg"), + onClick = { openRepositoryDialog(gitManager) } + ) - ) - Text("Open repository") - - } - - Button(onClick = {}) { - Image( - painter = painterResource("open.svg"), - contentDescription = null, - colorFilter = ColorFilter.tint(contentColorFor(MaterialTheme.colors.primary)) - - ) - Text("Clone repository") - } - - Button(onClick = {}) { - Image( - painter = painterResource("open.svg"), - contentDescription = null, - colorFilter = ColorFilter.tint(contentColorFor(MaterialTheme.colors.primary)) - - ) - Text("Init a new repository") - } + ButtonTile( + title = "Clone repository", + painter = painterResource("open.svg"), + onClick = {} + ) } } } +@Composable +fun ButtonTile( + title: String, + painter: Painter, + onClick: () -> Unit, +) { + OutlinedButton( + onClick = onClick, + modifier = Modifier.size(width = 200.dp, height = 56.dp) + ) { + Image( + modifier = Modifier + .size(24.dp) + .padding(end = 8.dp), + painter = painter, + contentDescription = null, + colorFilter = ColorFilter.tint(MaterialTheme.colors.primary), + ) + Text( + text = title, + ) + } +} \ No newline at end of file