Created custom implementation of context menu and added new icons
@ -27,6 +27,7 @@ dependencies {
|
|||||||
implementation(compose.desktop.currentOs)
|
implementation(compose.desktop.currentOs)
|
||||||
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
|
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
|
||||||
implementation(compose.desktop.components.splitPane)
|
implementation(compose.desktop.components.splitPane)
|
||||||
|
implementation(compose("org.jetbrains.compose.ui:ui-util"))
|
||||||
implementation("org.eclipse.jgit:org.eclipse.jgit:6.2.0.202206071550-r")
|
implementation("org.eclipse.jgit:org.eclipse.jgit:6.2.0.202206071550-r")
|
||||||
implementation("org.apache.sshd:sshd-core:2.9.0")
|
implementation("org.apache.sshd:sshd-core:2.9.0")
|
||||||
implementation("com.google.dagger:dagger:2.43.2")
|
implementation("com.google.dagger:dagger:2.43.2")
|
||||||
@ -56,7 +57,7 @@ tasks.withType<KotlinCompile> {
|
|||||||
|
|
||||||
compose.desktop {
|
compose.desktop {
|
||||||
application {
|
application {
|
||||||
mainClass = "MainKt"
|
mainClass = "com.jetpackduba.gitnuro.MainKt"
|
||||||
|
|
||||||
nativeDistributions {
|
nativeDistributions {
|
||||||
includeAllModules = true
|
includeAllModules = true
|
||||||
|
@ -63,7 +63,7 @@ fun rememberNetworkImageOrNull(url: String, placeHolderImageRes: String? = null)
|
|||||||
val cacheImageUsed = remember { ValueHolder(false) }
|
val cacheImageUsed = remember { ValueHolder(false) }
|
||||||
|
|
||||||
var image by remember(url) {
|
var image by remember(url) {
|
||||||
val cachedImage = NetworkImageLoader.loadCachedImage(url)
|
val cachedImage = networkImageLoader.loadCachedImage(url)
|
||||||
|
|
||||||
val image: ImageBitmap? = when {
|
val image: ImageBitmap? = when {
|
||||||
cachedImage != null -> {
|
cachedImage != null -> {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import com.jetpackduba.gitnuro.App
|
package com.jetpackduba.gitnuro
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val main = App()
|
val main = App()
|
||||||
|
@ -27,6 +27,7 @@ val lightTheme = ColorsScheme(
|
|||||||
hoverScrollbar = Color(0xFF0070D8),
|
hoverScrollbar = Color(0xFF0070D8),
|
||||||
diffLineAdded = Color(0xFFd7ebd0),
|
diffLineAdded = Color(0xFFd7ebd0),
|
||||||
diffLineRemoved = Color(0xFFf0d4d4),
|
diffLineRemoved = Color(0xFFf0d4d4),
|
||||||
|
isLight = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ val darkBlueTheme = ColorsScheme(
|
|||||||
hoverScrollbar = Color(0xFFCCCCCC),
|
hoverScrollbar = Color(0xFFCCCCCC),
|
||||||
diffLineAdded = Color(0xFF566f5a),
|
diffLineAdded = Color(0xFF566f5a),
|
||||||
diffLineRemoved = Color(0xFF6f585e),
|
diffLineRemoved = Color(0xFF6f585e),
|
||||||
|
isLight = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
val darkGrayTheme = ColorsScheme(
|
val darkGrayTheme = ColorsScheme(
|
||||||
@ -83,4 +84,5 @@ val darkGrayTheme = ColorsScheme(
|
|||||||
hoverScrollbar = Color(0xFFCCCCCC),
|
hoverScrollbar = Color(0xFFCCCCCC),
|
||||||
diffLineAdded = Color(0xFF5b7059),
|
diffLineAdded = Color(0xFF5b7059),
|
||||||
diffLineRemoved = Color(0xFF74595c),
|
diffLineRemoved = Color(0xFF74595c),
|
||||||
|
isLight = false,
|
||||||
)
|
)
|
@ -14,7 +14,6 @@ import kotlinx.serialization.encoding.Decoder
|
|||||||
import kotlinx.serialization.encoding.Encoder
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
|
|
||||||
// TODO Add line added + removed colors, graph colors and icons color for added/modified/removed files.
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ColorsScheme(
|
data class ColorsScheme(
|
||||||
val primary: Color,
|
val primary: Color,
|
||||||
@ -42,6 +41,7 @@ data class ColorsScheme(
|
|||||||
val hoverScrollbar: Color,
|
val hoverScrollbar: Color,
|
||||||
val diffLineAdded: Color,
|
val diffLineAdded: Color,
|
||||||
val diffLineRemoved: Color,
|
val diffLineRemoved: Color,
|
||||||
|
val isLight: Boolean,
|
||||||
) {
|
) {
|
||||||
fun toComposeColors(): Colors {
|
fun toComposeColors(): Colors {
|
||||||
return Colors(
|
return Colors(
|
||||||
@ -57,7 +57,7 @@ data class ColorsScheme(
|
|||||||
onBackground = this.primaryText,
|
onBackground = this.primaryText,
|
||||||
onSurface = this.primaryText,
|
onSurface = this.primaryText,
|
||||||
onError = this.onError,
|
onError = this.onError,
|
||||||
isLight = true, // property specific for some colors, we don't care about this as all our components are customized
|
isLight = isLight,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ fun typography() = Typography(
|
|||||||
body2 = TextStyle(
|
body2 = TextStyle(
|
||||||
fontSize = 13.sp,
|
fontSize = 13.sp,
|
||||||
color = MaterialTheme.colors.primaryTextColor,
|
color = MaterialTheme.colors.primaryTextColor,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
letterSpacing = LETTER_SPACING.sp,
|
letterSpacing = LETTER_SPACING.sp,
|
||||||
),
|
),
|
||||||
caption = TextStyle(
|
caption = TextStyle(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.ui
|
package com.jetpackduba.gitnuro.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuArea
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
@ -16,11 +15,11 @@ import com.jetpackduba.gitnuro.extensions.simpleName
|
|||||||
import com.jetpackduba.gitnuro.theme.secondaryTextColor
|
import com.jetpackduba.gitnuro.theme.secondaryTextColor
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.branchContextMenuItems
|
import com.jetpackduba.gitnuro.ui.context_menu.branchContextMenuItems
|
||||||
import com.jetpackduba.gitnuro.viewmodels.BranchesViewModel
|
import com.jetpackduba.gitnuro.viewmodels.BranchesViewModel
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Branches(
|
fun Branches(
|
||||||
branchesViewModel: BranchesViewModel,
|
branchesViewModel: BranchesViewModel,
|
||||||
@ -69,7 +68,7 @@ private fun BranchLineEntry(
|
|||||||
onPushToRemoteBranch: () -> Unit,
|
onPushToRemoteBranch: () -> Unit,
|
||||||
onPullFromRemoteBranch: () -> Unit,
|
onPullFromRemoteBranch: () -> Unit,
|
||||||
) {
|
) {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
branchContextMenuItems(
|
branchContextMenuItems(
|
||||||
branch = branch,
|
branch = branch,
|
||||||
|
@ -21,6 +21,7 @@ import com.jetpackduba.gitnuro.viewmodels.CommitChangesStatus
|
|||||||
import com.jetpackduba.gitnuro.viewmodels.CommitChangesViewModel
|
import com.jetpackduba.gitnuro.viewmodels.CommitChangesViewModel
|
||||||
import com.jetpackduba.gitnuro.extensions.*
|
import com.jetpackduba.gitnuro.extensions.*
|
||||||
import com.jetpackduba.gitnuro.theme.*
|
import com.jetpackduba.gitnuro.theme.*
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
import org.eclipse.jgit.diff.DiffEntry
|
||||||
@ -228,7 +229,7 @@ fun CommitLogChanges(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
items(items = diffEntries) { diffEntry ->
|
items(items = diffEntries) { diffEntry ->
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
commitedChangesEntriesContextMenuItems(
|
commitedChangesEntriesContextMenuItems(
|
||||||
diffEntry,
|
diffEntry,
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
@file:OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
|
@file:OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
|
||||||
package com.jetpackduba.gitnuro.ui
|
package com.jetpackduba.gitnuro.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuArea
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@ -23,6 +21,7 @@ import com.jetpackduba.gitnuro.theme.primaryTextColor
|
|||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
||||||
import com.jetpackduba.gitnuro.ui.components.VerticalExpandable
|
import com.jetpackduba.gitnuro.ui.components.VerticalExpandable
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.remoteBranchesContextMenu
|
import com.jetpackduba.gitnuro.ui.context_menu.remoteBranchesContextMenu
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.remoteContextMenu
|
import com.jetpackduba.gitnuro.ui.context_menu.remoteContextMenu
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.EditRemotesDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.EditRemotesDialog
|
||||||
@ -30,6 +29,7 @@ import com.jetpackduba.gitnuro.viewmodels.RemoteView
|
|||||||
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
|
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Remotes(
|
fun Remotes(
|
||||||
remotesViewModel: RemotesViewModel,
|
remotesViewModel: RemotesViewModel,
|
||||||
@ -85,7 +85,6 @@ fun Remotes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RemoteRow(
|
private fun RemoteRow(
|
||||||
remote: RemoteView,
|
remote: RemoteView,
|
||||||
@ -106,7 +105,7 @@ private fun RemoteRow(
|
|||||||
val branches = remote.remoteInfo.branchesList
|
val branches = remote.remoteInfo.branchesList
|
||||||
Column {
|
Column {
|
||||||
branches.forEach { branch ->
|
branches.forEach { branch ->
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
remoteBranchesContextMenu(
|
remoteBranchesContextMenu(
|
||||||
onDeleteBranch = { onDeleteBranch(branch) }
|
onDeleteBranch = { onDeleteBranch(branch) }
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
@file:OptIn(ExperimentalFoundationApi::class)
|
|
||||||
|
|
||||||
package com.jetpackduba.gitnuro.ui
|
package com.jetpackduba.gitnuro.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuArea
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@ -11,6 +7,8 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenuElement
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.stashesContextMenuItems
|
import com.jetpackduba.gitnuro.ui.context_menu.stashesContextMenuItems
|
||||||
import com.jetpackduba.gitnuro.viewmodels.StashStatus
|
import com.jetpackduba.gitnuro.viewmodels.StashStatus
|
||||||
import com.jetpackduba.gitnuro.viewmodels.StashesViewModel
|
import com.jetpackduba.gitnuro.viewmodels.StashesViewModel
|
||||||
@ -58,9 +56,9 @@ fun Stashes(
|
|||||||
private fun StashRow(
|
private fun StashRow(
|
||||||
stash: RevCommit,
|
stash: RevCommit,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
contextItems: List<ContextMenuItem>,
|
contextItems: List<ContextMenuElement>,
|
||||||
) {
|
) {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = { contextItems }
|
items = { contextItems }
|
||||||
) {
|
) {
|
||||||
SideMenuSubentry(
|
SideMenuSubentry(
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.ui
|
package com.jetpackduba.gitnuro.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuArea
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
@ -15,11 +13,11 @@ import com.jetpackduba.gitnuro.theme.secondaryTextColor
|
|||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
||||||
import com.jetpackduba.gitnuro.ui.components.Tooltip
|
import com.jetpackduba.gitnuro.ui.components.Tooltip
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.submoduleContextMenuItems
|
import com.jetpackduba.gitnuro.ui.context_menu.submoduleContextMenuItems
|
||||||
import com.jetpackduba.gitnuro.viewmodels.SubmodulesViewModel
|
import com.jetpackduba.gitnuro.viewmodels.SubmodulesViewModel
|
||||||
import org.eclipse.jgit.submodule.SubmoduleStatus
|
import org.eclipse.jgit.submodule.SubmoduleStatus
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Submodules(
|
fun Submodules(
|
||||||
submodulesViewModel: SubmodulesViewModel,
|
submodulesViewModel: SubmodulesViewModel,
|
||||||
@ -42,13 +40,12 @@ fun Submodules(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SubmoduleLineEntry(
|
private fun SubmoduleLineEntry(
|
||||||
submodulePair: Pair<String, SubmoduleStatus>,
|
submodulePair: Pair<String, SubmoduleStatus>,
|
||||||
onInitializeModule: () -> Unit,
|
onInitializeModule: () -> Unit,
|
||||||
) {
|
) {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
submoduleContextMenuItems(
|
submoduleContextMenuItems(
|
||||||
submodulePair.second,
|
submodulePair.second,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.ui
|
package com.jetpackduba.gitnuro.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuArea
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@ -9,6 +8,7 @@ import androidx.compose.ui.res.painterResource
|
|||||||
import com.jetpackduba.gitnuro.extensions.simpleName
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.tagContextMenuItems
|
import com.jetpackduba.gitnuro.ui.context_menu.tagContextMenuItems
|
||||||
import com.jetpackduba.gitnuro.viewmodels.TagsViewModel
|
import com.jetpackduba.gitnuro.viewmodels.TagsViewModel
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
@ -47,7 +47,7 @@ private fun TagRow(
|
|||||||
onCheckoutTag: () -> Unit,
|
onCheckoutTag: () -> Unit,
|
||||||
onDeleteTag: () -> Unit,
|
onDeleteTag: () -> Unit,
|
||||||
) {
|
) {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
tagContextMenuItems(
|
tagContextMenuItems(
|
||||||
onCheckoutTag = onCheckoutTag,
|
onCheckoutTag = onCheckoutTag,
|
||||||
|
@ -35,14 +35,11 @@ import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
|||||||
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||||
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
||||||
import com.jetpackduba.gitnuro.ui.components.SecondaryButton
|
import com.jetpackduba.gitnuro.ui.components.SecondaryButton
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.DropDownContent
|
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.DropDownContentData
|
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.EntryType
|
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.statusEntriesContextMenuItems
|
|
||||||
import com.jetpackduba.gitnuro.viewmodels.StageStatus
|
import com.jetpackduba.gitnuro.viewmodels.StageStatus
|
||||||
import com.jetpackduba.gitnuro.viewmodels.StatusViewModel
|
import com.jetpackduba.gitnuro.viewmodels.StatusViewModel
|
||||||
import com.jetpackduba.gitnuro.extensions.*
|
import com.jetpackduba.gitnuro.extensions.*
|
||||||
import com.jetpackduba.gitnuro.theme.*
|
import com.jetpackduba.gitnuro.theme.*
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.*
|
||||||
import org.eclipse.jgit.lib.RepositoryState
|
import org.eclipse.jgit.lib.RepositoryState
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -496,7 +493,7 @@ private fun EntriesList(
|
|||||||
lazyListState: LazyListState,
|
lazyListState: LazyListState,
|
||||||
onDiffEntrySelected: (StatusEntry) -> Unit,
|
onDiffEntrySelected: (StatusEntry) -> Unit,
|
||||||
onDiffEntryOptionSelected: (StatusEntry) -> Unit,
|
onDiffEntryOptionSelected: (StatusEntry) -> Unit,
|
||||||
onGenerateContextMenu: (StatusEntry) -> List<ContextMenuItem>,
|
onGenerateContextMenu: (StatusEntry) -> List<ContextMenuElement>,
|
||||||
onAllAction: () -> Unit,
|
onAllAction: () -> Unit,
|
||||||
allActionTitle: String,
|
allActionTitle: String,
|
||||||
selectedEntryType: DiffEntryType?,
|
selectedEntryType: DiffEntryType?,
|
||||||
@ -571,7 +568,7 @@ private fun FileEntry(
|
|||||||
actionColor: Color,
|
actionColor: Color,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
onButtonClick: () -> Unit,
|
onButtonClick: () -> Unit,
|
||||||
onGenerateContextMenu: (StatusEntry) -> List<ContextMenuItem>,
|
onGenerateContextMenu: (StatusEntry) -> List<ContextMenuElement>,
|
||||||
) {
|
) {
|
||||||
val hoverInteraction = remember { MutableInteractionSource() }
|
val hoverInteraction = remember { MutableInteractionSource() }
|
||||||
val isHovered by hoverInteraction.collectIsHoveredAsState()
|
val isHovered by hoverInteraction.collectIsHoveredAsState()
|
||||||
@ -582,7 +579,7 @@ private fun FileEntry(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.hoverable(hoverInteraction)
|
.hoverable(hoverInteraction)
|
||||||
) {
|
) {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
onGenerateContextMenu(statusEntry)
|
onGenerateContextMenu(statusEntry)
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.components
|
package com.jetpackduba.gitnuro.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuArea
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -10,6 +8,8 @@ import androidx.compose.material.MaterialTheme
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenuElement
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -21,13 +21,13 @@ fun <T> SideMenuPanel(
|
|||||||
onExpand: () -> Unit,
|
onExpand: () -> Unit,
|
||||||
itemContent: @Composable (T) -> Unit,
|
itemContent: @Composable (T) -> Unit,
|
||||||
headerHoverIcon: @Composable (() -> Unit)? = null,
|
headerHoverIcon: @Composable (() -> Unit)? = null,
|
||||||
contextItems: () -> List<ContextMenuItem> = { emptyList() },
|
contextItems: () -> List<ContextMenuElement> = { emptyList() },
|
||||||
) {
|
) {
|
||||||
VerticalExpandable(
|
VerticalExpandable(
|
||||||
isExpanded = isExpanded,
|
isExpanded = isExpanded,
|
||||||
onExpand = onExpand,
|
onExpand = onExpand,
|
||||||
header = {
|
header = {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = contextItems
|
items = contextItems
|
||||||
) {
|
) {
|
||||||
SideMenuEntry(
|
SideMenuEntry(
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import com.jetpackduba.gitnuro.extensions.isHead
|
import com.jetpackduba.gitnuro.extensions.isHead
|
||||||
import com.jetpackduba.gitnuro.extensions.simpleLogName
|
import com.jetpackduba.gitnuro.extensions.simpleLogName
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun branchContextMenuItems(
|
fun branchContextMenuItems(
|
||||||
branch: Ref,
|
branch: Ref,
|
||||||
isCurrentBranch: Boolean,
|
isCurrentBranch: Boolean,
|
||||||
@ -19,47 +17,51 @@ fun branchContextMenuItems(
|
|||||||
onDeleteRemoteBranch: () -> Unit = {},
|
onDeleteRemoteBranch: () -> Unit = {},
|
||||||
onPushToRemoteBranch: () -> Unit,
|
onPushToRemoteBranch: () -> Unit,
|
||||||
onPullFromRemoteBranch: () -> Unit,
|
onPullFromRemoteBranch: () -> Unit,
|
||||||
): List<ContextMenuItem> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf<ContextMenuItem>().apply {
|
return mutableListOf<ContextMenuElement>().apply {
|
||||||
if (!isCurrentBranch) {
|
if (!isCurrentBranch) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Checkout branch",
|
label = "Checkout branch",
|
||||||
|
icon = { painterResource("start.svg") },
|
||||||
onClick = onCheckoutBranch
|
onClick = onCheckoutBranch
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if (currentBranch != null && !currentBranch.isHead) {
|
if (currentBranch != null && !currentBranch.isHead) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Merge branch",
|
label = "Merge branch",
|
||||||
onClick = onMergeBranch
|
onClick = onMergeBranch
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Rebase branch",
|
label = "Rebase branch",
|
||||||
onClick = onRebaseBranch
|
onClick = onRebaseBranch
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add(ContextMenuElement.ContextSeparator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isLocal && !isCurrentBranch) {
|
if (isLocal && !isCurrentBranch) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Delete branch",
|
label = "Delete branch",
|
||||||
|
icon = { painterResource("delete.svg") },
|
||||||
onClick = onDeleteBranch
|
onClick = onDeleteBranch
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!isLocal && currentBranch != null && !currentBranch.isHead) {
|
if (!isLocal && currentBranch != null && !currentBranch.isHead) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Push ${currentBranch.simpleLogName} to ${branch.simpleLogName}",
|
label = "Push ${currentBranch.simpleLogName} to ${branch.simpleLogName}",
|
||||||
onClick = onPushToRemoteBranch
|
onClick = onPushToRemoteBranch
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Pull ${branch.simpleLogName} to ${currentBranch.simpleLogName}",
|
label = "Pull ${branch.simpleLogName} to ${currentBranch.simpleLogName}",
|
||||||
onClick = onPullFromRemoteBranch
|
onClick = onPullFromRemoteBranch
|
||||||
)
|
)
|
||||||
@ -67,11 +69,16 @@ fun branchContextMenuItems(
|
|||||||
}
|
}
|
||||||
if (!isLocal) {
|
if (!isLocal) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Delete remote branch",
|
label = "Delete remote branch",
|
||||||
|
icon = { painterResource("delete.svg") },
|
||||||
onClick = onDeleteRemoteBranch
|
onClick = onDeleteRemoteBranch
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(lastOrNull() == ContextMenuElement.ContextSeparator) {
|
||||||
|
removeLast()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package com.jetpackduba.gitnuro.ui.context_menu
|
|||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
import androidx.compose.foundation.ContextMenuItem
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
import org.eclipse.jgit.diff.DiffEntry
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@ -9,19 +10,20 @@ fun commitedChangesEntriesContextMenuItems(
|
|||||||
diffEntry: DiffEntry,
|
diffEntry: DiffEntry,
|
||||||
onBlame: () -> Unit,
|
onBlame: () -> Unit,
|
||||||
onHistory: () -> Unit,
|
onHistory: () -> Unit,
|
||||||
): List<ContextMenuItem> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf<ContextMenuItem>().apply {
|
return mutableListOf<ContextMenuElement>().apply {
|
||||||
if (diffEntry.changeType != DiffEntry.ChangeType.ADD ||
|
if (diffEntry.changeType != DiffEntry.ChangeType.ADD ||
|
||||||
diffEntry.changeType != DiffEntry.ChangeType.DELETE
|
diffEntry.changeType != DiffEntry.ChangeType.DELETE
|
||||||
) {
|
) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Blame file",
|
label = "Blame file",
|
||||||
|
icon = { painterResource("blame.svg") },
|
||||||
onClick = onBlame,
|
onClick = onBlame,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "File history",
|
label = "File history",
|
||||||
onClick = onHistory,
|
onClick = onHistory,
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,226 @@
|
|||||||
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
|
import androidx.compose.foundation.*
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.awt.awtEventOrNull
|
||||||
|
import androidx.compose.ui.draw.shadow
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
|
import androidx.compose.ui.input.pointer.*
|
||||||
|
import androidx.compose.ui.unit.*
|
||||||
|
import androidx.compose.ui.util.fastAll
|
||||||
|
import androidx.compose.ui.window.Popup
|
||||||
|
import androidx.compose.ui.window.PopupPositionProvider
|
||||||
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
|
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||||
|
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
||||||
|
import com.jetpackduba.gitnuro.theme.secondaryTextColor
|
||||||
|
import java.awt.event.MouseEvent
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
private var lastCheck: Long = 0
|
||||||
|
private const val MIN_TIME_BETWEEN_POPUPS = 20
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ContextMenu(items: () -> List<ContextMenuElement>, function: @Composable () -> Unit) {
|
||||||
|
Box(modifier = Modifier.contextMenu(items), propagateMinConstraints = true) {
|
||||||
|
function()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun Modifier.contextMenu(items: () -> List<ContextMenuElement>): Modifier {
|
||||||
|
var lastMouseEventState by remember { mutableStateOf<MouseEvent?>(null) }
|
||||||
|
val mod = this.pointerInput(Unit) {
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
val lastMouseEvent = awaitPointerEventScope { awaitEventFirstDown() }
|
||||||
|
val mouseEvent = lastMouseEvent.awtEventOrNull
|
||||||
|
|
||||||
|
if (mouseEvent != null) {
|
||||||
|
if (!lastMouseEvent.toString().contains("MOUSE_MOVED"))
|
||||||
|
println(lastMouseEvent.toString())
|
||||||
|
|
||||||
|
if (lastMouseEvent.button.isSecondary) {
|
||||||
|
val currentCheck = System.currentTimeMillis()
|
||||||
|
if (lastCheck != 0L && currentCheck - lastCheck < MIN_TIME_BETWEEN_POPUPS) {
|
||||||
|
println("IGNORE POPUP TRIGGERED!")
|
||||||
|
} else {
|
||||||
|
println("POPUP TRIGGERED!")
|
||||||
|
println("X: ${mouseEvent.x}\nY: ${mouseEvent.y}")
|
||||||
|
lastCheck = currentCheck
|
||||||
|
|
||||||
|
lastMouseEventState = mouseEvent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastMouseEventState != null) {
|
||||||
|
showPopup(
|
||||||
|
lastMouseEventState!!.x,
|
||||||
|
lastMouseEventState!!.y,
|
||||||
|
items(),
|
||||||
|
onDismissRequest = { lastMouseEventState = null })
|
||||||
|
}
|
||||||
|
|
||||||
|
return mod
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun showPopup(x: Int, y: Int, contextMenuElements: List<ContextMenuElement>, onDismissRequest: () -> Unit) {
|
||||||
|
LaunchedEffect(contextMenuElements) {
|
||||||
|
println("Items count ${contextMenuElements.count()}")
|
||||||
|
}
|
||||||
|
Popup(
|
||||||
|
focusable = true,
|
||||||
|
popupPositionProvider = object : PopupPositionProvider {
|
||||||
|
override fun calculatePosition(
|
||||||
|
anchorBounds: IntRect,
|
||||||
|
windowSize: IntSize,
|
||||||
|
layoutDirection: LayoutDirection,
|
||||||
|
popupContentSize: IntSize
|
||||||
|
): IntOffset {
|
||||||
|
val resultY = if (popupContentSize.height > windowSize.height) {
|
||||||
|
0 // If the popup is taller than the window itself
|
||||||
|
} else if (y + popupContentSize.height > windowSize.height) {
|
||||||
|
// If the end of the popup would go out of bounds.
|
||||||
|
// Move the Y a bit to the top to make it fit
|
||||||
|
y - abs(windowSize.height - (y + popupContentSize.height))
|
||||||
|
} else {
|
||||||
|
y
|
||||||
|
}
|
||||||
|
|
||||||
|
val resultX = if (x + popupContentSize.width > windowSize.width && popupContentSize.width < x) {
|
||||||
|
// If the end of the popup would go out of bounds.
|
||||||
|
// Move the X a bit to the left to make it fit
|
||||||
|
x - abs(windowSize.width - (x + popupContentSize.width))
|
||||||
|
} else {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntOffset(resultX, resultY)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDismissRequest = onDismissRequest
|
||||||
|
) {
|
||||||
|
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.shadow(4.dp)
|
||||||
|
.width(300.dp)
|
||||||
|
.background(MaterialTheme.colors.background)
|
||||||
|
.run {
|
||||||
|
return@run if (!MaterialTheme.colors.isLight) {
|
||||||
|
this.border(1.dp, MaterialTheme.colors.primaryTextColor.copy(alpha = 0.2f))
|
||||||
|
} else
|
||||||
|
this
|
||||||
|
}
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.focusable()
|
||||||
|
.onPreviewKeyEvent { keyEvent ->
|
||||||
|
if (keyEvent.matchesBinding(KeybindingOption.EXIT)) {
|
||||||
|
onDismissRequest()
|
||||||
|
true
|
||||||
|
} else
|
||||||
|
false
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
|
||||||
|
for (item in contextMenuElements) {
|
||||||
|
when (item) {
|
||||||
|
is ContextMenuElement.ContextTextEntry -> TextEntry(item, onDismissRequest = onDismissRequest)
|
||||||
|
ContextMenuElement.ContextSeparator -> Separator()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Separator() {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(1.dp)
|
||||||
|
.background(MaterialTheme.colors.primaryTextColor.copy(alpha = 0.4f))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun focusRequesterAndModifier(): Pair<FocusRequester, Modifier> {
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
return focusRequester to Modifier.focusRequester(focusRequester)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TextEntry(contextTextEntry: ContextMenuElement.ContextTextEntry, onDismissRequest: () -> Unit) {
|
||||||
|
val icon = contextTextEntry.icon
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable {
|
||||||
|
onDismissRequest()
|
||||||
|
contextTextEntry.onClick()
|
||||||
|
}
|
||||||
|
.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
Box(modifier = Modifier.size(24.dp).padding(end = 8.dp)) {
|
||||||
|
if (icon != null) {
|
||||||
|
Icon(
|
||||||
|
painter = icon(),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
tint = (MaterialTheme.colors.secondaryTextColor.copy(alpha = 0.8f))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
contextTextEntry.label,
|
||||||
|
style = MaterialTheme.typography.body2,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface ContextMenuElement {
|
||||||
|
data class ContextTextEntry(
|
||||||
|
val label: String,
|
||||||
|
val icon: @Composable (() -> Painter)? = null,
|
||||||
|
val onClick: () -> Unit = {}
|
||||||
|
) : ContextMenuElement
|
||||||
|
|
||||||
|
object ContextSeparator : ContextMenuElement
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun AwaitPointerEventScope.awaitEventFirstDown(): PointerEvent {
|
||||||
|
var event: PointerEvent
|
||||||
|
do {
|
||||||
|
event = awaitPointerEvent()
|
||||||
|
} while (
|
||||||
|
!event.changes.fastAll { it.changedToDown() }
|
||||||
|
)
|
||||||
|
return event
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
|
|
||||||
fun logContextMenu(
|
fun logContextMenu(
|
||||||
onCheckoutCommit: () -> Unit,
|
onCheckoutCommit: () -> Unit,
|
||||||
@ -12,32 +11,38 @@ fun logContextMenu(
|
|||||||
onResetBranch: () -> Unit,
|
onResetBranch: () -> Unit,
|
||||||
onRebaseInteractive: () -> Unit,
|
onRebaseInteractive: () -> Unit,
|
||||||
) = listOf(
|
) = listOf(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Checkout commit",
|
label = "Checkout commit",
|
||||||
|
icon = { painterResource("start.svg") },
|
||||||
onClick = onCheckoutCommit
|
onClick = onCheckoutCommit
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Create branch",
|
label = "Create branch",
|
||||||
|
icon = { painterResource("branch.svg") },
|
||||||
onClick = onCreateNewBranch
|
onClick = onCreateNewBranch
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Create tag",
|
label = "Create tag",
|
||||||
|
icon = { painterResource("tag.svg") },
|
||||||
onClick = onCreateNewTag
|
onClick = onCreateNewTag
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextSeparator,
|
||||||
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Rebase interactive",
|
label = "Rebase interactive",
|
||||||
onClick = onRebaseInteractive
|
onClick = onRebaseInteractive
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Revert commit",
|
label = "Revert commit",
|
||||||
|
icon = { painterResource("revert.svg") },
|
||||||
onClick = onRevertCommit
|
onClick = onRevertCommit
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Cherry-pick commit",
|
label = "Cherry-pick commit",
|
||||||
onClick = onCherryPickCommit
|
onClick = onCherryPickCommit
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Reset current branch to this commit",
|
label = "Reset current branch to this commit",
|
||||||
|
icon = { painterResource("undo.svg") },
|
||||||
onClick = onResetBranch
|
onClick = onResetBranch
|
||||||
),
|
),
|
||||||
)
|
)
|
@ -4,13 +4,15 @@ package com.jetpackduba.gitnuro.ui.context_menu
|
|||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
import androidx.compose.foundation.ContextMenuItem
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
|
||||||
fun remoteBranchesContextMenu(
|
fun remoteBranchesContextMenu(
|
||||||
onDeleteBranch: () -> Unit
|
onDeleteBranch: () -> Unit
|
||||||
): List<ContextMenuItem> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf(
|
return listOf(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Delete remote branch",
|
label = "Delete remote branch",
|
||||||
|
icon = { painterResource("delete.svg") },
|
||||||
onClick = onDeleteBranch
|
onClick = onDeleteBranch
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun remoteContextMenu(
|
fun remoteContextMenu(
|
||||||
onEditRemotes: () -> Unit,
|
onEditRemotes: () -> Unit,
|
||||||
) = listOf(
|
): List<ContextMenuElement> = listOf(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Edit remotes",
|
label = "Edit remotes",
|
||||||
onClick = onEditRemotes
|
onClick = onEditRemotes
|
||||||
),
|
),
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import com.jetpackduba.gitnuro.git.workspace.StatusEntry
|
|
||||||
import com.jetpackduba.gitnuro.git.workspace.StatusType
|
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun stagedEntriesContextMenuItems(
|
|
||||||
diffEntry: StatusEntry,
|
|
||||||
onReset: () -> Unit,
|
|
||||||
): List<ContextMenuItem> {
|
|
||||||
return mutableListOf<ContextMenuItem>().apply {
|
|
||||||
if (diffEntry.statusType != StatusType.ADDED) {
|
|
||||||
add(
|
|
||||||
ContextMenuItem(
|
|
||||||
label = "Reset",
|
|
||||||
onClick = onReset,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +1,26 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun stashesContextMenuItems(
|
fun stashesContextMenuItems(
|
||||||
onApply: () -> Unit,
|
onApply: () -> Unit,
|
||||||
onPop: () -> Unit,
|
onPop: () -> Unit,
|
||||||
onDelete: () -> Unit,
|
onDelete: () -> Unit,
|
||||||
): List<ContextMenuItem> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf(
|
return listOf(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Apply stash",
|
label = "Apply stash",
|
||||||
|
icon = { painterResource("apply_stash.svg") },
|
||||||
onClick = onApply
|
onClick = onApply
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Pop stash",
|
label = "Pop stash",
|
||||||
|
icon = { painterResource("apply_stash.svg") },
|
||||||
onClick = onPop
|
onClick = onPop
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Drop stash",
|
label = "Drop stash",
|
||||||
|
icon = { painterResource("delete.svg") },
|
||||||
onClick = onDelete
|
onClick = onDelete
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import com.jetpackduba.gitnuro.git.workspace.StatusEntry
|
import com.jetpackduba.gitnuro.git.workspace.StatusEntry
|
||||||
import com.jetpackduba.gitnuro.git.workspace.StatusType
|
import com.jetpackduba.gitnuro.git.workspace.StatusType
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun statusEntriesContextMenuItems(
|
fun statusEntriesContextMenuItems(
|
||||||
statusEntry: StatusEntry,
|
statusEntry: StatusEntry,
|
||||||
entryType: EntryType,
|
entryType: EntryType,
|
||||||
@ -13,26 +11,28 @@ fun statusEntriesContextMenuItems(
|
|||||||
onDelete: () -> Unit = {},
|
onDelete: () -> Unit = {},
|
||||||
onBlame: () -> Unit,
|
onBlame: () -> Unit,
|
||||||
onHistory: () -> Unit,
|
onHistory: () -> Unit,
|
||||||
): List<ContextMenuItem> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf<ContextMenuItem>().apply {
|
return mutableListOf<ContextMenuElement>().apply {
|
||||||
if (statusEntry.statusType != StatusType.ADDED) {
|
if (statusEntry.statusType != StatusType.ADDED) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Reset",
|
label = "Reset",
|
||||||
|
icon = { painterResource("undo.svg") },
|
||||||
onClick = onReset,
|
onClick = onReset,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (statusEntry.statusType != StatusType.REMOVED) {
|
if (statusEntry.statusType != StatusType.REMOVED) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Blame file",
|
label = "Blame file",
|
||||||
|
icon = { painterResource("blame.svg") },
|
||||||
onClick = onBlame,
|
onClick = onBlame,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "File history",
|
label = "File history",
|
||||||
onClick = onHistory,
|
onClick = onHistory,
|
||||||
)
|
)
|
||||||
@ -45,8 +45,9 @@ fun statusEntriesContextMenuItems(
|
|||||||
statusEntry.statusType != StatusType.REMOVED
|
statusEntry.statusType != StatusType.REMOVED
|
||||||
) {
|
) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Delete file",
|
label = "Delete file",
|
||||||
|
icon = { painterResource("delete.svg") },
|
||||||
onClick = onDelete,
|
onClick = onDelete,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import org.eclipse.jgit.submodule.SubmoduleStatus
|
import org.eclipse.jgit.submodule.SubmoduleStatus
|
||||||
import org.eclipse.jgit.submodule.SubmoduleStatusType
|
import org.eclipse.jgit.submodule.SubmoduleStatusType
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun submoduleContextMenuItems(
|
fun submoduleContextMenuItems(
|
||||||
submoduleStatus: SubmoduleStatus,
|
submoduleStatus: SubmoduleStatus,
|
||||||
onInitializeModule: () -> Unit,
|
onInitializeModule: () -> Unit,
|
||||||
): List<ContextMenuItem> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf<ContextMenuItem>().apply {
|
return mutableListOf<ContextMenuElement>().apply {
|
||||||
if (submoduleStatus.type == SubmoduleStatusType.UNINITIALIZED) {
|
if (submoduleStatus.type == SubmoduleStatusType.UNINITIALIZED) {
|
||||||
add(
|
add(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Initialize submodule",
|
label = "Initialize submodule",
|
||||||
onClick = onInitializeModule
|
onClick = onInitializeModule
|
||||||
)
|
)
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.context_menu
|
package com.jetpackduba.gitnuro.ui.context_menu
|
||||||
|
|
||||||
import androidx.compose.foundation.ContextMenuItem
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun tagContextMenuItems(
|
fun tagContextMenuItems(
|
||||||
onCheckoutTag: () -> Unit,
|
onCheckoutTag: () -> Unit,
|
||||||
onDeleteTag: () -> Unit,
|
onDeleteTag: () -> Unit,
|
||||||
): List<ContextMenuItem> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf(
|
return mutableListOf(
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Checkout tag",
|
label = "Checkout tag",
|
||||||
|
icon = { painterResource("start.svg") },
|
||||||
onClick = onCheckoutTag
|
onClick = onCheckoutTag
|
||||||
),
|
),
|
||||||
ContextMenuItem(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Delete tag",
|
label = "Delete tag",
|
||||||
|
icon = { painterResource("delete.svg") },
|
||||||
onClick = onDeleteTag
|
onClick = onDeleteTag
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -38,19 +38,14 @@ import androidx.compose.ui.text.font.FontStyle
|
|||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.jetpackduba.gitnuro.app.extensions.*
|
|
||||||
import com.jetpackduba.gitnuro.git.workspace.StatusSummary
|
import com.jetpackduba.gitnuro.git.workspace.StatusSummary
|
||||||
import com.jetpackduba.gitnuro.git.graph.GraphCommitList
|
import com.jetpackduba.gitnuro.git.graph.GraphCommitList
|
||||||
import com.jetpackduba.gitnuro.git.graph.GraphNode
|
import com.jetpackduba.gitnuro.git.graph.GraphNode
|
||||||
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||||
import com.jetpackduba.gitnuro.app.theme.*
|
|
||||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||||
import com.jetpackduba.gitnuro.ui.components.AvatarImage
|
import com.jetpackduba.gitnuro.ui.components.AvatarImage
|
||||||
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.branchContextMenuItems
|
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.logContextMenu
|
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.tagContextMenuItems
|
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.NewBranchDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.NewBranchDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.NewTagDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.NewTagDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.ResetBranchDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.ResetBranchDialog
|
||||||
@ -59,6 +54,7 @@ import com.jetpackduba.gitnuro.viewmodels.LogStatus
|
|||||||
import com.jetpackduba.gitnuro.viewmodels.LogViewModel
|
import com.jetpackduba.gitnuro.viewmodels.LogViewModel
|
||||||
import com.jetpackduba.gitnuro.extensions.*
|
import com.jetpackduba.gitnuro.extensions.*
|
||||||
import com.jetpackduba.gitnuro.theme.*
|
import com.jetpackduba.gitnuro.theme.*
|
||||||
|
import com.jetpackduba.gitnuro.ui.context_menu.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
import org.eclipse.jgit.lib.RepositoryState
|
import org.eclipse.jgit.lib.RepositoryState
|
||||||
@ -750,7 +746,7 @@ fun CommitLine(
|
|||||||
onRevCommitSelected: () -> Unit,
|
onRevCommitSelected: () -> Unit,
|
||||||
onRebaseInteractive: () -> Unit,
|
onRebaseInteractive: () -> Unit,
|
||||||
) {
|
) {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
logContextMenu(
|
logContextMenu(
|
||||||
onCheckoutCommit = { logViewModel.checkoutCommit(graphNode) },
|
onCheckoutCommit = { logViewModel.checkoutCommit(graphNode) },
|
||||||
@ -1122,7 +1118,7 @@ fun TagChip(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun RefChip(
|
fun RefChip(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
@ -1130,7 +1126,7 @@ fun RefChip(
|
|||||||
icon: String,
|
icon: String,
|
||||||
color: Color,
|
color: Color,
|
||||||
onCheckoutRef: () -> Unit,
|
onCheckoutRef: () -> Unit,
|
||||||
contextMenuItemsList: () -> List<ContextMenuItem>,
|
contextMenuItemsList: () -> List<ContextMenuElement>,
|
||||||
endingContent: @Composable () -> Unit = {},
|
endingContent: @Composable () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
@ -1141,7 +1137,7 @@ fun RefChip(
|
|||||||
.combinedClickable(onDoubleClick = onCheckoutRef, onClick = {})
|
.combinedClickable(onDoubleClick = onCheckoutRef, onClick = {})
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.pointerHoverIcon(PointerIconDefaults.Hand)
|
||||||
) {
|
) {
|
||||||
ContextMenuArea(
|
ContextMenu(
|
||||||
items = contextMenuItemsList
|
items = contextMenuItemsList
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
1
src/main/resources/blame.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><path d="M0,0h24v24H0V0z" fill="none"/></g><g><path d="M7,9H2V7h5V9z M7,12H2v2h5V12z M20.59,19l-3.83-3.83C15.96,15.69,15.02,16,14,16c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5 c0,1.02-0.31,1.96-0.83,2.75L22,17.59L20.59,19z M17,11c0-1.65-1.35-3-3-3s-3,1.35-3,3s1.35,3,3,3S17,12.65,17,11z M2,19h10v-2H2 V19z"/></g></svg>
|
After Width: | Height: | Size: 455 B |
@ -1,4 +1,7 @@
|
|||||||
<?xml version="1.0" ?>
|
<svg width="54" height="54" viewBox="0 0 54 54" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<svg height="1024" width="640" xmlns="http://www.w3.org/2000/svg">
|
<line x1="14" y1="15" x2="14" y2="40" stroke="black" stroke-width="4"/>
|
||||||
<path d="M512 192c-70.625 0-128 57.344-128 128 0 47.219 25.875 88.062 64 110.281V448c0 0 0 128-128 128-53.062 0-94.656 11.375-128 28.812V302.28099999999995c38.156-22.219 64-63.062 64-110.281 0-70.656-57.344-128-128-128S0 121.34400000000005 0 192c0 47.219 25.844 88.062 64 110.281V721.75C25.844 743.938 0 784.75 0 832c0 70.625 57.344 128 128 128s128-57.375 128-128c0-33.5-13.188-63.75-34.25-86.625C240.375 722.5 270.656 704 320 704c254 0 256-256 256-256v-17.719c38.125-22.219 64-63.062 64-110.281C640 249.34400000000005 582.625 192 512 192zM128 128c35.406 0 64 28.594 64 64s-28.594 64-64 64-64-28.594-64-64S92.594 128 128 128zM128 896c-35.406 0-64-28.625-64-64 0-35.312 28.594-64 64-64s64 28.688 64 64C192 867.375 163.406 896 128 896zM512 384c-35.375 0-64-28.594-64-64s28.625-64 64-64 64 28.594 64 64S547.375 384 512 384z"/>
|
<circle cx="14" cy="8" r="6" stroke="black" stroke-width="4"/>
|
||||||
|
<path d="M46 19C46 22.3137 43.3137 25 40 25C36.6863 25 34 22.3137 34 19C34 15.6863 36.6863 13 40 13C43.3137 13 46 15.6863 46 19Z" stroke="black" stroke-width="4"/>
|
||||||
|
<circle cx="14" cy="46" r="6" stroke="black" stroke-width="4"/>
|
||||||
|
<path d="M13.8484 38.636L15.9135 36.8638C18.4322 34.7022 21.6179 33.4731 24.9357 33.3828L31.5028 33.204C35.676 33.0904 39 29.6747 39 25.5V25.5" stroke="black" stroke-width="4"/>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 924 B After Width: | Height: | Size: 644 B |
@ -1,4 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 6c2.62 0 4.88 1.86 5.39 4.43l.3 1.5 1.53.11c1.56.1 2.78 1.41 2.78 2.96 0 1.65-1.35 3-3 3H6c-2.21 0-4-1.79-4-4 0-2.05 1.53-3.76 3.56-3.97l1.07-.11.5-.95C8.08 7.14 9.94 6 12 6m0-2C9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96C18.67 6.59 15.64 4 12 4z"/></svg>
|
||||||
<path d="M0 0h24v24H0z" fill="none"/>
|
|
||||||
<path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 480 B |
1
src/main/resources/delete.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z"/></svg>
|
After Width: | Height: | Size: 252 B |
1
src/main/resources/revert.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9c-4.97 0-9 4.03-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.51 0-2.91-.49-4.06-1.3l-1.42 1.44C8.04 20.3 9.94 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9z"/></svg>
|
After Width: | Height: | Size: 377 B |
1
src/main/resources/start.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M14.59,7.41L18.17,11H6v2h12.17l-3.59,3.59L16,18l6-6l-6-6L14.59,7.41z M2,6v12h2V6H2z"/></svg>
|
After Width: | Height: | Size: 279 B |
@ -1,4 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58s1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41s-.23-1.06-.59-1.42zM13 20.01L4 11V4h7v-.01l9 9-7 7.02z"/><circle cx="6.5" cy="6.5" r="1.5"/></svg>
|
||||||
<path d="M0 0h24v24H0z" fill="none"/>
|
|
||||||
<path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 402 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/><path d="M20,6h-8l-2-2H4C2.9,4,2.01,4.9,2.01,6L2,18c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M14,16H6v-2h8V16z M18,12H6v-2h12V12z"/></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/><path d="M20,6h-8l-2-2H4C2.9,4,2.01,4.9,2.01,6L2,18c0,1.1,0.9,2,2,2h16.77c0.68,0,1.23-0.56,1.23-1.23V8C22,6.9,21.1,6,20,6z M20,18L4,18V6h5.17l2,2H20V18z M18,12H6v-2h12V12z M14,16H6v-2h8V16z"/></g></svg>
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 383 B |
1
src/main/resources/undo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"/></svg>
|
After Width: | Height: | Size: 301 B |