Skip to content

Commit

Permalink
[IconPack] Allow to paste icon from clipboard
Browse files Browse the repository at this point in the history
  • Loading branch information
egorikftp committed Nov 11, 2024
1 parent 1ccc4b9 commit bf62bf1
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 69 deletions.
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

0 comments on commit bf62bf1

Please sign in to comment.