Browse Source

Added mouse hover interactivity to the desktop version of app.

pull/5/head
spvessel 4 years ago
parent
commit
345c409833
  1. 2
      examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/model/ContentState.kt
  2. 2
      examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/view/AndroidHover.kt
  3. 4
      examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/style/Palette.kt
  4. 2
      examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/view/PointerMoveFilter.kt
  5. 23
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/model/ContentState.kt
  6. 2
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/AppUI.kt
  7. 33
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/FullImageScreen.kt
  8. 84
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/MainScreen.kt
  9. 2
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/MouseHover.kt
  10. 4
      examples/imageviewer/desktop/src/main/kotlin/imageviewer/Main.kt

2
examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/model/ContentState.kt

@ -159,7 +159,7 @@ object ContentState {
}
// application content initialization
fun initData() {
private fun initData() {
if (isAppUIReady.value)
return

2
examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/view/ActualAndroid.kt → examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/view/AndroidHover.kt

@ -3,7 +3,7 @@ package example.imageviewer.view
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
actual fun Modifier.maybePointerMoveFilter(
actual fun Modifier.hover(
onEnter: () -> Boolean,
onExit: () -> Boolean,
onMove: (Offset) -> Boolean

4
examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/style/Palette.kt

@ -21,7 +21,11 @@ val DarkGreen = Color(16, 139, 102)
val Gray = Color.DarkGray
val LightGray = Color(100, 100, 100)
val DarkGray = Color(32, 32, 32)
val PreviewImageAreaHoverColor = Color(45, 45, 45)
val ToastBackground = Color(23, 23, 23)
val MiniatureColor = Color(50, 50, 50)
val MiniatureHoverColor = Color(60, 60, 60)
val Foreground = Color(210, 210, 210)
val TranslucentBlack = Color(0, 0, 0, 60)
val TranslucentWhite = Color(255, 255, 255, 20)
val Transparent = Color.Transparent

2
examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/view/PointerMoveFilter.kt

@ -3,7 +3,7 @@ package example.imageviewer.view
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
expect fun Modifier.maybePointerMoveFilter(
expect fun Modifier.hover(
onEnter: () -> Boolean = { true },
onExit: () -> Boolean = { true },
onMove: (Offset) -> Boolean = { true }

23
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/model/ContentState.kt

@ -32,9 +32,24 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
class ContentState(
private val repository: ImageRepository
) {
object ContentState {
private lateinit var repository: ImageRepository
private lateinit var uriRepository: String
fun applyContent(uriRepository: String): ContentState {
if (this::uriRepository.isInitialized && this.uriRepository == uriRepository) {
return this
}
this.uriRepository = uriRepository
repository = ImageRepository(uriRepository)
isAppUIReady.value = false
initData()
return this
}
private val executor: ExecutorService by lazy { Executors.newFixedThreadPool(2) }
private val isAppUIReady = mutableStateOf(false)
@ -124,7 +139,7 @@ class ContentState(
}
// application content initialization
fun initData() {
private fun initData() {
if (isAppUIReady.value)
return

2
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/AppUI.kt

@ -32,8 +32,6 @@ private val state: MutableState<Boolean> = mutableStateOf(false)
@Composable
fun BuildAppUI(content: ContentState) {
content.initData()
Surface(
modifier = Modifier.fillMaxSize(),
color = Gray

33
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/FullImageScreen.kt

@ -19,6 +19,7 @@ import java.awt.image.BufferedImage
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.ScrollableRow
import androidx.compose.foundation.Image
@ -41,6 +42,8 @@ import androidx.compose.foundation.layout.preferredHeight
import androidx.compose.foundation.layout.preferredSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Surface
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.dp
import example.imageviewer.core.FilterType
import example.imageviewer.model.AppState
@ -51,6 +54,8 @@ import example.imageviewer.style.DarkGreen
import example.imageviewer.style.Foreground
import example.imageviewer.style.MiniatureColor
import example.imageviewer.style.Transparent
import example.imageviewer.style.TranslucentBlack
import example.imageviewer.style.TranslucentWhite
import example.imageviewer.style.icBack
import example.imageviewer.style.icFilterGrayscaleOn
import example.imageviewer.style.icFilterGrayscaleOff
@ -106,8 +111,11 @@ fun setToolBar(
text: String,
content: ContentState
) {
Surface(color = MiniatureColor, modifier = Modifier.preferredHeight(44.dp)) {
val backButtonHover = remember { mutableStateOf(false) }
Surface(
color = MiniatureColor,
modifier = Modifier.preferredHeight(44.dp)
) {
Row(modifier = Modifier.padding(end = 30.dp)) {
Surface(
color = Transparent,
@ -115,6 +123,16 @@ fun setToolBar(
shape = CircleShape
) {
Clickable(
modifier = Modifier.hover(
onEnter = {
backButtonHover.value = true
false
},
onExit = {
backButtonHover.value = false
false
})
.background(color = if (backButtonHover.value) TranslucentBlack else Transparent),
onClick = {
if (content.isContentReady()) {
content.restoreMainImage()
@ -160,11 +178,22 @@ fun FilterButton(
type: FilterType,
modifier: Modifier = Modifier.preferredSize(38.dp)
) {
val filterButtonHover = remember { mutableStateOf(false) }
Surface(
color = Transparent,
shape = CircleShape
) {
Clickable(
modifier = Modifier.hover(
onEnter = {
filterButtonHover.value = true
false
},
onExit = {
filterButtonHover.value = false
false
})
.background(color = if (filterButtonHover.value) TranslucentBlack else Transparent),
onClick = { content.toggleFilter(type)}
) {
Image(

84
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/MainScreen.kt

@ -15,7 +15,12 @@
*/
package example.imageviewer.view
import androidx.compose.foundation.*
import androidx.compose.foundation.clickable
import androidx.compose.foundation.background
import androidx.compose.foundation.Box
import androidx.compose.foundation.Text
import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollableColumn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.RectangleShape
@ -53,6 +58,10 @@ import example.imageviewer.style.DarkGray
import example.imageviewer.style.DarkGreen
import example.imageviewer.style.Foreground
import example.imageviewer.style.Transparent
import example.imageviewer.style.TranslucentBlack
import example.imageviewer.style.TranslucentWhite
import example.imageviewer.style.PreviewImageAreaHoverColor
import example.imageviewer.style.MiniatureHoverColor
import example.imageviewer.style.MiniatureColor
import example.imageviewer.style.LightGray
import example.imageviewer.style.icRefresh
@ -112,7 +121,7 @@ fun setTopContent(content: ContentState) {
@Composable
fun setTitleBar(text: String, content: ContentState) {
val refreshButtonHover = remember { mutableStateOf(false) }
TopAppBar(
backgroundColor = DarkGreen,
title = {
@ -128,6 +137,16 @@ fun setTitleBar(text: String, content: ContentState) {
shape = CircleShape
) {
Clickable(
modifier = Modifier.hover(
onEnter = {
refreshButtonHover.value = true
false
},
onExit = {
refreshButtonHover.value = false
false
})
.background(color = if (refreshButtonHover.value) TranslucentBlack else Transparent),
onClick = {
if (content.isContentReady())
content.refresh()
@ -144,12 +163,23 @@ fun setTitleBar(text: String, content: ContentState) {
@Composable
fun setPreviewImageUI(content: ContentState) {
Clickable(onClick = {
val previewImageHover = remember { mutableStateOf(false) }
Clickable(
modifier = Modifier.hover(
onEnter = {
previewImageHover.value = true
false
},
onExit = {
previewImageHover.value = false
false
})
.background(color = if (previewImageHover.value) PreviewImageAreaHoverColor else DarkGray),
onClick = {
AppState.screenState(ScreenType.FullscreenImage)
}) {
Card(
backgroundColor = DarkGray,
backgroundColor = Transparent,
modifier = Modifier.preferredHeight(250.dp),
shape = RectangleShape,
elevation = 1.dp
@ -173,29 +203,28 @@ fun setMiniatureUI(
picture: Picture,
content: ContentState
) {
val active = remember { mutableStateOf(false) }
val cardHover = remember { mutableStateOf(false) }
val infoButtonHover = remember { mutableStateOf(false) }
Card(
backgroundColor = MiniatureColor,
backgroundColor = if (cardHover.value) MiniatureHoverColor else MiniatureColor,
modifier = Modifier.padding(start = 10.dp, end = 10.dp).preferredHeight(70.dp)
.fillMaxWidth()
.hover(onEnter = {
cardHover.value = true
false
},
onExit = {
cardHover.value = false
false
})
.clickable {
content.setMainImage(picture)
},
shape = RectangleShape,
elevation = 2.dp
elevation = 20.dp
) {
Row(modifier = Modifier.padding(end = 30.dp)
) {
Row(modifier = Modifier
.padding(end = 30.dp)
.maybePointerMoveFilter(onEnter = {
active.value = true
false
},
onExit = {
active.value = false
false
}
)
.background(color = if (active.value) Color.LightGray else Color.Black)) {
Clickable(
onClick = {
content.fullscreen(picture)
@ -213,18 +242,27 @@ fun setMiniatureUI(
}
Text(
text = picture.name,
color = if (active.value) Color.Red else Foreground,
color = Foreground,
modifier = Modifier
.weight(1f)
.align(Alignment.CenterVertically)
.padding(start = 16.dp),
fontSize = TextUnit.Sp(if (active.value) 40 else 16),
style = MaterialTheme.typography.body1
)
Clickable(
modifier = Modifier.preferredHeight(70.dp)
.preferredWidth(30.dp),
.preferredWidth(30.dp)
.hover(
onEnter = {
infoButtonHover.value = true
false
},
onExit = {
infoButtonHover.value = false
false
})
.background(color = if (infoButtonHover.value) TranslucentWhite else Transparent),
onClick = {
showPopUpMessage(
"${ResString.picture} " +

2
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/ActualDesktop.kt → examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/MouseHover.kt

@ -4,7 +4,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.pointerMoveFilter
actual fun Modifier.maybePointerMoveFilter(
actual fun Modifier.hover(
onEnter: () -> Boolean,
onExit: () -> Boolean,
onMove: (Offset) -> Boolean

4
examples/imageviewer/desktop/src/main/kotlin/imageviewer/Main.kt

@ -23,8 +23,8 @@ import example.imageviewer.model.ImageRepository
fun main() {
val content = ContentState(
ImageRepository("https://spvessel.com/iv/images/fetching.list")
val content = ContentState.applyContent(
"https://spvessel.com/iv/images/fetching.list"
)
AppWindow("ImageViewer", getPreferredWindowSize(800, 1000)).show {

Loading…
Cancel
Save