diff --git a/app/src/main/java/org/mydomain/myscan/view/CameraScreen.kt b/app/src/main/java/org/mydomain/myscan/view/CameraScreen.kt index 8d23f60..2038bf7 100644 --- a/app/src/main/java/org/mydomain/myscan/view/CameraScreen.kt +++ b/app/src/main/java/org/mydomain/myscan/view/CameraScreen.kt @@ -36,11 +36,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -54,7 +51,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalConfiguration @@ -116,7 +112,7 @@ fun CameraScreen( ) }, pageList = { - CameraCapturedPagesRow( + CommonPageList( pageIds = pageIds, imageLoader = { id -> viewModel.getBitmap(id) }, onPageClick = { index -> viewModel.navigateTo(Screen.FinalizeDocument(index)) }, @@ -280,46 +276,6 @@ fun CameraScreenFooter( } } -@Composable -fun CameraCapturedPagesRow( - pageIds: List, - imageLoader: (String) -> Bitmap?, - onPageClick: (Int) -> Unit, - listState: LazyListState, -) { - if (pageIds.isEmpty()) return - - LazyRow ( - state = listState, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - itemsIndexed(pageIds) { index, id -> - val image = imageLoader(id) - if (image != null) { - Box { - val bitmap = image.asImageBitmap() - val modifier = - if (bitmap.height > bitmap.width) - Modifier.height(120.dp) - else - Modifier.width(120.dp) - Image( - bitmap = bitmap, - contentDescription = "Page ${index + 1}", - modifier = modifier - .clickable { onPageClick(index) } - .clip(RoundedCornerShape(4.dp)) - ) - } - } - } - } -} - - @Preview(showBackground = true) @Composable fun CameraScreenPreview() { @@ -352,7 +308,7 @@ private fun ScreenPreview(captureState: CaptureState) { } }, pageList = { - CameraCapturedPagesRow( + CommonPageList( pageIds = listOf(1, 2, 2, 2).map { "gallica.bnf.fr-bpt6k5530456s-$it.jpg" }, imageLoader = { id -> context.assets.open(id).use { input -> diff --git a/app/src/main/java/org/mydomain/myscan/view/DocumentScreen.kt b/app/src/main/java/org/mydomain/myscan/view/DocumentScreen.kt index 8c6c6a7..29aac64 100644 --- a/app/src/main/java/org/mydomain/myscan/view/DocumentScreen.kt +++ b/app/src/main/java/org/mydomain/myscan/view/DocumentScreen.kt @@ -18,21 +18,14 @@ import android.graphics.Bitmap import android.graphics.BitmapFactory import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add @@ -64,7 +57,6 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Size -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview @@ -188,7 +180,7 @@ private fun DocumentPreview( ) { Icon(imageVector = Icons.Outlined.Delete, contentDescription = "Delete page") } - Text("${currentPageIndex.value + 1} / ${pageIds.size}", + Text("${currentPageIndex.intValue + 1} / ${pageIds.size}", color = MaterialTheme.colorScheme.inverseOnSurface, modifier = Modifier .align(Alignment.BottomEnd) @@ -208,39 +200,12 @@ private fun PageList( toCameraScreen: () -> Unit ) { Box { - LazyRow( - contentPadding = PaddingValues(8.dp), - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp) - .background(MaterialTheme.colorScheme.secondaryContainer), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - itemsIndexed (pageIds) { index, id -> - // TODO Use small images rather than big ones - val image = imageLoader(id) - if (image != null) { - val bitmap = image.asImageBitmap() - val isSelected = index == currentPageIndex.value - val borderColor = - if (isSelected) MaterialTheme.colorScheme.primary else Color.Transparent - val modifier = - if (bitmap.height > bitmap.width) - Modifier.height(120.dp) - else - Modifier.width(120.dp) - Image( - bitmap = bitmap, - contentDescription = null, - modifier = modifier - .padding(4.dp) - .border(2.dp, borderColor) - .clickable { currentPageIndex.value = index } - ) - } - } - } + CommonPageList( + pageIds, + imageLoader, + onPageClick = { index -> currentPageIndex.value = index }, + currentPageIndex = currentPageIndex.value, + ) SmallFloatingActionButton( onClick = toCameraScreen, modifier = Modifier diff --git a/app/src/main/java/org/mydomain/myscan/view/PageList.kt b/app/src/main/java/org/mydomain/myscan/view/PageList.kt new file mode 100644 index 0000000..124aae9 --- /dev/null +++ b/app/src/main/java/org/mydomain/myscan/view/PageList.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2025 Pierre-Yves Nicolas + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +package org.mydomain.myscan.view + +import android.graphics.Bitmap +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material3.MaterialTheme +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.asImageBitmap +import androidx.compose.ui.unit.dp + +@Composable +fun CommonPageList( + pageIds: List, + imageLoader: (String) -> Bitmap?, + onPageClick: (Int) -> Unit, + listState: LazyListState = rememberLazyListState(), + currentPageIndex: Int? = null, +) { + if (pageIds.isEmpty()) return + LazyRow ( + state = listState, + contentPadding = PaddingValues(4.dp), + modifier = Modifier + .fillMaxWidth() + .background(MaterialTheme.colorScheme.secondaryContainer), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + itemsIndexed(pageIds) { index, id -> + // TODO Use small images rather than big ones + val image = imageLoader(id) + if (image != null) { + val bitmap = image.asImageBitmap() + val isSelected = index == currentPageIndex + val borderColor = + if (isSelected) MaterialTheme.colorScheme.primary else Color.Transparent + val modifier = + if (bitmap.height > bitmap.width) + Modifier.height(120.dp) + else + Modifier.width(120.dp) + Image( + bitmap = bitmap, + contentDescription = null, + modifier = modifier + .padding(4.dp) + .border(2.dp, borderColor) + .clickable { onPageClick(index) } + ) + } + } + } +}