Moved menu to be shown only when a repo is open and improved welcome screen

This commit is contained in:
Abdelilah El Aissaoui 2021-10-04 20:56:03 +02:00
parent 7af1756a8e
commit e34ded9e29
4 changed files with 253 additions and 240 deletions

View file

@ -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<String>) {
.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<String>) {
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<Boolean> = 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
)
}
}
}
}

134
src/main/kotlin/ui/GMenu.kt Normal file
View file

@ -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<Boolean> = 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
)
}
}
}

View file

@ -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)
}
)
}
}
}
}
}

View file

@ -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,
)
}
}