Skip to content

Commit

Permalink
Updated imageviewer example to use CoroutineScope (loading and proces…
Browse files Browse the repository at this point in the history
…sing images).
  • Loading branch information
Rsedaikin committed Aug 3, 2021
1 parent 4697b0f commit 8b16eea
Show file tree
Hide file tree
Showing 20 changed files with 525 additions and 518 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package example.imageviewer
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.activity.compose.setContent
import example.imageviewer.view.BuildAppUI
import example.imageviewer.view.AppUI
import example.imageviewer.model.ContentState
import example.imageviewer.model.ImageRepository

Expand All @@ -17,7 +17,7 @@ class MainActivity : AppCompatActivity() {
)

setContent {
BuildAppUI(content)
AppUI(content)
}
}
}
2 changes: 1 addition & 1 deletion examples/imageviewer/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ buildscript {

dependencies {
// __LATEST_COMPOSE_RELEASE_VERSION__
classpath("org.jetbrains.compose:compose-gradle-plugin:1.0.0-alpha1-rc1")
classpath("org.jetbrains.compose:compose-gradle-plugin:1.0.0-alpha1-rc3")
classpath("com.android.tools.build:gradle:7.0.0")
classpath(kotlin("gradle-plugin", version = "1.5.21"))
}
Expand Down
40 changes: 28 additions & 12 deletions ...example/imageviewer/model/ContentState.kt → .../imageviewer/model/AndroidContentState.kt
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ object ContentState {
this.uriRepository = uriRepository
repository = ImageRepository(uriRepository)
appliedFilters = FiltersManager(context)
isAppUIReady.value = false
isContentReady.value = false

initData()

Expand All @@ -50,9 +50,14 @@ object ContentState {
return context.resources.configuration.orientation
}

private val isAppUIReady = mutableStateOf(false)
private val isAppReady = mutableStateOf(false)
fun isAppReady(): Boolean {
return isAppReady.value
}

private val isContentReady = mutableStateOf(false)
fun isContentReady(): Boolean {
return isAppUIReady.value
return isContentReady.value
}

fun getString(id: Int): String {
Expand Down Expand Up @@ -142,7 +147,7 @@ object ContentState {

// application content initialization
private fun initData() {
if (isAppUIReady.value)
if (isContentReady.value)
return

val directory = context.cacheDir.absolutePath
Expand All @@ -158,7 +163,7 @@ object ContentState {
getString(R.string.repo_invalid),
context
)
isAppUIReady.value = true
onContentReady()
}
return@execute
}
Expand All @@ -171,7 +176,7 @@ object ContentState {
getString(R.string.repo_empty),
context
)
isAppUIReady.value = true
onContentReady()
}
} else {
val picture = loadFullImage(imageList[0])
Expand All @@ -186,7 +191,7 @@ object ContentState {
mainImage.value = MainImageWrapper.getImage()
currentImageIndex.value = MainImageWrapper.getId()
}
isAppUIReady.value = true
onContentReady()
}
}
} else {
Expand All @@ -195,7 +200,7 @@ object ContentState {
getString(R.string.no_internet),
context
)
isAppUIReady.value = true
onContentReady()
}
}
} catch (e: Exception) {
Expand All @@ -210,17 +215,18 @@ object ContentState {
}

fun fullscreen(picture: Picture) {
isAppUIReady.value = false
isContentReady.value = false
AppState.screenState(ScreenType.FullscreenImage)
setMainImage(picture)
}

fun setMainImage(picture: Picture) {
if (MainImageWrapper.getId() == picture.id) {
if (!isContentReady())
isAppUIReady.value = true
onContentReady()
return
}
isContentReady.value = false

executor.execute {
if (isInternetAvailable()) {
Expand All @@ -230,7 +236,7 @@ object ContentState {

handler.post {
wrapPictureIntoMainImage(fullSizePicture)
isAppUIReady.value = true
onContentReady()
}
} else {
handler.post {
Expand All @@ -244,6 +250,11 @@ object ContentState {
}
}

private fun onContentReady() {
isContentReady.value = true
isAppReady.value = true
}

private fun wrapPictureIntoMainImage(picture: Picture) {
MainImageWrapper.wrapPicture(picture)
MainImageWrapper.saveOrigin()
Expand Down Expand Up @@ -282,8 +293,9 @@ object ContentState {
if (isInternetAvailable()) {
handler.post {
clearCache(context)
MainImageWrapper.clear()
miniatures.clear()
isAppUIReady.value = false
isContentReady.value = false
initData()
}
} else {
Expand Down Expand Up @@ -334,6 +346,10 @@ private object MainImageWrapper {
return (picture.value.name == "")
}

fun clear() {
picture.value = Picture(image = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
}

fun getName(): String {
return picture.value.name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import androidx.compose.ui.layout.ContentScale
import kotlin.math.pow
import kotlin.math.roundToInt
import example.imageviewer.view.DragHandler

fun scaleBitmapAspectRatio(
bitmap: Bitmap,
Expand Down Expand Up @@ -116,3 +119,77 @@ fun displayWidth(): Int {
fun displayHeight(): Int {
return Resources.getSystem().displayMetrics.heightPixels
}

fun cropBitmapByScale(bitmap: Bitmap, scale: Float, drag: DragHandler): Bitmap {
val crop = cropBitmapByBounds(
bitmap,
getDisplayBounds(bitmap),
scale,
drag
)
return Bitmap.createBitmap(
bitmap,
crop.left,
crop.top,
crop.right - crop.left,
crop.bottom - crop.top
)
}

fun cropBitmapByBounds(
bitmap: Bitmap,
bounds: Rect,
scaleFactor: Float,
drag: DragHandler
): Rect {
if (scaleFactor <= 1f)
return Rect(0, 0, bitmap.width, bitmap.height)

var scale = scaleFactor.toDouble().pow(1.4)

var boundW = (bounds.width() / scale).roundToInt()
var boundH = (bounds.height() / scale).roundToInt()

scale *= displayWidth() / bounds.width().toDouble()

val offsetX = drag.getAmount().x / scale
val offsetY = drag.getAmount().y / scale

if (boundW > bitmap.width) {
boundW = bitmap.width
}
if (boundH > bitmap.height) {
boundH = bitmap.height
}

val invisibleW = bitmap.width - boundW
var leftOffset = (invisibleW / 2.0 - offsetX).roundToInt().toFloat()

if (leftOffset > invisibleW) {
leftOffset = invisibleW.toFloat()
drag.getAmount().x = -((invisibleW / 2.0) * scale).roundToInt().toFloat()
}
if (leftOffset < 0) {
drag.getAmount().x = ((invisibleW / 2.0) * scale).roundToInt().toFloat()
leftOffset = 0f
}

val invisibleH = bitmap.height - boundH
var topOffset = (invisibleH / 2 - offsetY).roundToInt().toFloat()

if (topOffset > invisibleH) {
topOffset = invisibleH.toFloat()
drag.getAmount().y = -((invisibleH / 2.0) * scale).roundToInt().toFloat()
}
if (topOffset < 0) {
drag.getAmount().y = ((invisibleH / 2.0) * scale).roundToInt().toFloat()
topOffset = 0f
}

return Rect(
leftOffset.toInt(),
topOffset.toInt(),
(leftOffset + boundW).toInt(),
(topOffset + boundH).toInt()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ import example.imageviewer.model.ContentState
import example.imageviewer.style.Gray

@Composable
fun BuildAppUI(content: ContentState) {
fun AppUI(content: ContentState) {

Surface(
modifier = Modifier.fillMaxSize(),
color = Gray
) {
when (AppState.screenState()) {
ScreenType.Main -> {
setMainScreen(content)
ScreenType.MainScreen -> {
MainScreen(content)
}
ScreenType.FullscreenImage -> {
setImageFullScreen(content)
FullscreenImage(content)
}
}
}
Expand Down
Loading

0 comments on commit 8b16eea

Please sign in to comment.