Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IconPack] Allow to paste icon from clipboard #283

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,6 @@ import com.composegears.tiamat.rememberSaveableViewModel
import com.intellij.openapi.application.writeAction
import com.intellij.openapi.vfs.VirtualFileManager
import io.git.luolix.topposegears.valkyrie.service.GlobalEventsHandler.PendingPathData
import io.git.luolix.topposegears.valkyrie.ui.foundation.AppBarTitle
import io.git.luolix.topposegears.valkyrie.ui.foundation.BackAction
import io.git.luolix.topposegears.valkyrie.ui.foundation.CloseAction
import io.git.luolix.topposegears.valkyrie.ui.foundation.SettingsAction
import io.git.luolix.topposegears.valkyrie.ui.foundation.TopAppBar
import io.git.luolix.topposegears.valkyrie.ui.foundation.WeightSpacer
import io.git.luolix.topposegears.valkyrie.ui.foundation.theme.PreviewTheme
import io.git.luolix.topposegears.valkyrie.ui.screen.mode.iconpack.conversion.IconPackConversionState.BatchProcessing.ExportingState
import io.git.luolix.topposegears.valkyrie.ui.screen.mode.iconpack.conversion.IconPackConversionState.BatchProcessing.IconPackCreationState
Expand Down Expand Up @@ -152,35 +146,13 @@ private fun IconPackConversionUi(

Box(
modifier = Modifier
.pointerInput(Unit) {
detectTapGestures(onTap = { focusManager.clearFocus() })
.pointerInput(state) {
if (state is IconPackCreationState) {
detectTapGestures(onTap = { focusManager.clearFocus() })
}
},
) {
Column(modifier = Modifier.fillMaxSize()) {
TopAppBar {
AnimatedContent(
targetState = state,
transitionSpec = { fadeIn() togetherWith fadeOut() },
contentKey = {
when (it) {
is IconsPickering, ExportingState, ImportValidationState -> 0
is IconPackCreationState -> 1
}
},
) { current ->
when (current) {
is IconsPickering, ExportingState, ImportValidationState -> {
BackAction(onBack = onBack)
}
is IconPackCreationState -> {
CloseAction(onClose = onReset)
}
}
}
AppBarTitle(title = "IconPack generation")
WeightSpacer()
SettingsAction(openSettings = openSettings)
}
AnimatedContent(
modifier = Modifier.fillMaxSize(),
targetState = state,
Expand All @@ -198,7 +170,11 @@ private fun IconPackConversionUi(
) { current ->
when (current) {
is IconsPickering -> {
IconPackPickerStateUi(onPickerEvent = onPickEvent)
IconPackPickerStateUi(
onPickerEvent = onPickEvent,
onBack = onBack,
openSettings = openSettings,
)
}
ExportingState -> {
LoadingStateUi(message = "Exporting icons...")
Expand All @@ -214,6 +190,8 @@ private fun IconPackConversionUi(
onUpdatePack = updatePack,
onPreviewClick = onPreviewClick,
onRenameIcon = onRenameIcon,
onClose = onReset,
openSettings = openSettings,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class IconPackConversionViewModel(
when (events) {
is PickerEvent.PickDirectory -> events.path.listDirectoryEntries().processFiles()
is PickerEvent.PickFiles -> events.paths.processFiles()
is PickerEvent.ClipboardText -> processText(events.text)
}
}

Expand Down Expand Up @@ -257,6 +258,30 @@ class IconPackConversionViewModel(
_state.updateState { IconsPickering }
}

private fun processText(text: String) = viewModelScope.launch(Dispatchers.Default) {
val iconName = "IconName"

val output = runCatching { SvgXmlParser.toIrImageVector(text, iconName) }.getOrNull()

val icon = when (output) {
null -> BatchIcon.Broken(iconName = IconName(iconName))
else -> BatchIcon.Valid(
iconName = IconName(output.iconName),
iconType = output.iconType,
iconPack = inMemorySettings.current.buildDefaultIconPack(),
irImageVector = output.irImageVector,
)
}
_state.updateState {
val icons = listOf(icon)

BatchProcessing.IconPackCreationState(
icons = icons,
exportEnabled = icons.isAllIconsValid(),
)
}
}

private fun List<Path>.processFiles() = viewModelScope.launch(Dispatchers.Default) {
val paths = filter { it.isRegularFile() && (it.isXml || it.isSvg) }

Expand Down Expand Up @@ -316,4 +341,5 @@ sealed interface ConversionEvent {
sealed interface PickerEvent {
data class PickDirectory(val path: Path) : PickerEvent
data class PickFiles(val paths: List<Path>) : PickerEvent
data class ClipboardText(val text: String) : PickerEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ import io.git.luolix.topposegears.valkyrie.ir.IR_STUB
import io.git.luolix.topposegears.valkyrie.parser.svgxml.IconNameFormatter
import io.git.luolix.topposegears.valkyrie.parser.svgxml.util.IconType.SVG
import io.git.luolix.topposegears.valkyrie.parser.svgxml.util.IconType.XML
import io.git.luolix.topposegears.valkyrie.ui.foundation.AppBarTitle
import io.git.luolix.topposegears.valkyrie.ui.foundation.CenterVerticalRow
import io.git.luolix.topposegears.valkyrie.ui.foundation.CloseAction
import io.git.luolix.topposegears.valkyrie.ui.foundation.IconButton
import io.git.luolix.topposegears.valkyrie.ui.foundation.SettingsAction
import io.git.luolix.topposegears.valkyrie.ui.foundation.TopAppBar
import io.git.luolix.topposegears.valkyrie.ui.foundation.VerticalScrollbar
import io.git.luolix.topposegears.valkyrie.ui.foundation.WeightSpacer
import io.git.luolix.topposegears.valkyrie.ui.foundation.icons.ValkyrieIcons
import io.git.luolix.topposegears.valkyrie.ui.foundation.icons.Visibility
import io.git.luolix.topposegears.valkyrie.ui.foundation.rememberMutableState
Expand All @@ -57,40 +62,50 @@ import io.git.luolix.topposegears.valkyrie.ui.screen.mode.iconpack.conversion.ui.bat
@Composable
fun BatchProcessingStateUi(
state: IconPackCreationState,
onClose: () -> Unit,
openSettings: () -> Unit,
onDeleteIcon: (IconName) -> Unit,
onUpdatePack: (BatchIcon, String) -> Unit,
onPreviewClick: (IconName) -> Unit,
onRenameIcon: (BatchIcon, IconName) -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier) {
val lazyGridState = rememberLazyGridState()
Column(modifier = modifier) {
TopAppBar {
CloseAction(onClose = onClose)
AppBarTitle(title = "IconPack generation")
WeightSpacer()
SettingsAction(openSettings = openSettings)
}
Box {
val lazyGridState = rememberLazyGridState()

LazyVerticalGrid(
state = lazyGridState,
modifier = Modifier.fillMaxSize(),
columns = GridCells.Adaptive(300.dp),
contentPadding = PaddingValues(16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
items(items = state.icons, key = { it.id }) { batchIcon ->
when (batchIcon) {
is BatchIcon.Broken -> BrokenIconItem(
broken = batchIcon,
onDelete = onDeleteIcon,
)
is BatchIcon.Valid -> ValidIconItem(
icon = batchIcon,
onUpdatePack = onUpdatePack,
onDeleteIcon = onDeleteIcon,
onPreview = onPreviewClick,
onRenameIcon = onRenameIcon,
)
LazyVerticalGrid(
state = lazyGridState,
modifier = Modifier.fillMaxSize(),
columns = GridCells.Adaptive(300.dp),
contentPadding = PaddingValues(16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
items(items = state.icons, key = { it.id }) { batchIcon ->
when (batchIcon) {
is BatchIcon.Broken -> BrokenIconItem(
broken = batchIcon,
onDelete = onDeleteIcon,
)
is BatchIcon.Valid -> ValidIconItem(
icon = batchIcon,
onUpdatePack = onUpdatePack,
onDeleteIcon = onDeleteIcon,
onPreview = onPreviewClick,
onRenameIcon = onRenameIcon,
)
}
}
}
VerticalScrollbar(adapter = rememberScrollbarAdapter(lazyGridState))
}
VerticalScrollbar(adapter = rememberScrollbarAdapter(lazyGridState))
}
}

Expand Down Expand Up @@ -328,6 +343,8 @@ private fun BatchProcessingStatePreview() = PreviewTheme {
),
),
),
onClose = {},
openSettings = {},
onDeleteIcon = {},
onUpdatePack = { _, _ -> },
onPreviewClick = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -20,15 +22,14 @@ import io.git.luolix.topposegears.valkyrie.ir.IrImageVector
import io.git.luolix.topposegears.valkyrie.parser.ktfile.util.toComposeImageVector
import io.git.luolix.topposegears.valkyrie.ui.foundation.previewbg.BgType
import io.git.luolix.topposegears.valkyrie.ui.foundation.previewbg.PreviewBackground
import io.git.luolix.topposegears.valkyrie.ui.foundation.rememberMutableState
import io.git.luolix.topposegears.valkyrie.ui.foundation.theme.PreviewTheme

@Composable
fun IconPreviewBox(
irImageVector: IrImageVector,
modifier: Modifier = Modifier,
) {
var bgType by rememberMutableState { BgType.PixelGrid }
var bgType by rememberSaveable { mutableStateOf(BgType.PixelGrid) }

Box(
modifier = modifier
Expand Down
Loading