25 changed files with 212 additions and 171 deletions
@ -1,3 +0,0 @@ |
|||||||
<resources> |
|
||||||
<string name="app_name">Chat app</string> |
|
||||||
</resources> |
|
@ -1,3 +1,3 @@ |
|||||||
<resources> |
<resources> |
||||||
<string name="app_name">Chat app</string> |
<string name="app_name">Chat</string> |
||||||
</resources> |
</resources> |
@ -1,3 +1,3 @@ |
|||||||
<resources> |
<resources> |
||||||
<string name="app_name">Chat app</string> |
<string name="app_name">Falling Balls</string> |
||||||
</resources> |
</resources> |
@ -1,11 +1,17 @@ |
|||||||
|
compose.version=1.3.0-alpha01-dev827 |
||||||
|
kotlin.version=1.7.10 |
||||||
|
agp.version=7.0.4 |
||||||
|
org.gradle.jvmargs=-Xmx3g |
||||||
|
kotlin.code.style=official |
||||||
kotlin.native.cacheKind=none |
kotlin.native.cacheKind=none |
||||||
kotlin.native.useEmbeddableCompilerJar=true |
kotlin.native.useEmbeddableCompilerJar=true |
||||||
org.gradle.jvmargs=-Xmx3g |
|
||||||
kotlin.mpp.enableGranularSourceSetsMetadata=true |
|
||||||
kotlin.native.enableDependencyPropagation=false |
kotlin.native.enableDependencyPropagation=false |
||||||
|
kotlin.mpp.enableGranularSourceSetsMetadata=true |
||||||
# Enable kotlin/native experimental memory model |
# Enable kotlin/native experimental memory model |
||||||
kotlin.native.binary.memoryModel=experimental |
kotlin.native.binary.memoryModel=experimental |
||||||
compose.desktop.verbose=true |
compose.desktop.verbose=true |
||||||
|
android.useAndroidX=true |
||||||
|
kotlin.js.webpack.major.version=4 |
||||||
org.jetbrains.compose.experimental.jscanvas.enabled=true |
org.jetbrains.compose.experimental.jscanvas.enabled=true |
||||||
org.jetbrains.compose.experimental.macos.enabled=true |
org.jetbrains.compose.experimental.macos.enabled=true |
||||||
org.jetbrains.compose.experimental.uikit.enabled=true |
org.jetbrains.compose.experimental.uikit.enabled=true |
||||||
|
@ -1,11 +1,22 @@ |
|||||||
pluginManagement { |
pluginManagement { |
||||||
repositories { |
repositories { |
||||||
mavenLocal() |
mavenLocal() |
||||||
gradlePluginPortal() |
|
||||||
mavenCentral() |
mavenCentral() |
||||||
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") } |
gradlePluginPortal() |
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") |
||||||
google() |
google() |
||||||
} |
} |
||||||
|
|
||||||
|
plugins { |
||||||
|
val kotlinVersion = extra["kotlin.version"] as String |
||||||
|
kotlin("multiplatform").version(kotlinVersion) |
||||||
|
kotlin("android").version(kotlinVersion) |
||||||
|
|
||||||
|
val agpVersion = extra["agp.version"] as String |
||||||
|
id("com.android.application").version(agpVersion) |
||||||
|
|
||||||
|
val composeVersion = extra["compose.version"] as String |
||||||
|
id("org.jetbrains.compose").version(composeVersion) |
||||||
|
} |
||||||
} |
} |
||||||
rootProject.name = "minesweeper" |
rootProject.name = "minesweeper" |
||||||
|
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
package="org.jetbrains.minesweeper"> |
||||||
|
|
||||||
|
<application |
||||||
|
android:allowBackup="true" |
||||||
|
android:label="@string/app_name" |
||||||
|
android:supportsRtl="true" |
||||||
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar"> |
||||||
|
<activity |
||||||
|
android:exported="true" |
||||||
|
android:name="MainActivity" |
||||||
|
android:label="@string/app_name"> |
||||||
|
<intent-filter> |
||||||
|
<action android:name="android.intent.action.MAIN" /> |
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" /> |
||||||
|
</intent-filter> |
||||||
|
</activity> |
||||||
|
</application> |
||||||
|
|
||||||
|
</manifest> |
@ -0,0 +1,15 @@ |
|||||||
|
package org.jetbrains.minesweeper |
||||||
|
|
||||||
|
import android.os.Bundle |
||||||
|
import androidx.activity.compose.setContent |
||||||
|
import androidx.appcompat.app.AppCompatActivity |
||||||
|
import Game |
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() { |
||||||
|
override fun onCreate(savedInstanceState: Bundle?) { |
||||||
|
super.onCreate(savedInstanceState) |
||||||
|
setContent { |
||||||
|
Game() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.ui.graphics.painter.Painter |
||||||
|
|
||||||
|
@Composable |
||||||
|
actual fun loadImage(src: String): Painter = loadImageAsColoredRect(src) |
||||||
|
|
||||||
|
actual fun isMobileDevice() = true |
@ -0,0 +1,3 @@ |
|||||||
|
<resources> |
||||||
|
<string name="app_name">Minesweeper</string> |
||||||
|
</resources> |
@ -1,30 +1,47 @@ |
|||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi |
||||||
|
import androidx.compose.foundation.combinedClickable |
||||||
import androidx.compose.runtime.Composable |
import androidx.compose.runtime.Composable |
||||||
import androidx.compose.ui.Modifier |
import androidx.compose.ui.Modifier |
||||||
import androidx.compose.ui.input.pointer.* |
import androidx.compose.ui.input.pointer.* |
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class) |
||||||
@Composable |
@Composable |
||||||
fun Modifier.gameInteraction(open: () -> Unit, flag: () -> Unit, seek: () -> Unit): Modifier = |
fun Modifier.gameInteraction(open: () -> Unit, flag: () -> Unit, seek: () -> Unit): Modifier = |
||||||
pointerInput(open, flag, seek) { |
if (isMobileDevice()) { |
||||||
awaitPointerEventScope { |
combinedClickable( |
||||||
while (true) { |
onClick = { |
||||||
val event = awaitPointerEvent(PointerEventPass.Main) |
open() |
||||||
with(event) { |
}, |
||||||
if (type == PointerEventType.Press) { |
onDoubleClick = { |
||||||
// TODO does not work yet, all events are of Unknown type ( |
seek() |
||||||
val lmb = buttons.isPrimaryPressed |
}, |
||||||
val rmb = buttons.isSecondaryPressed |
onLongClick = { |
||||||
|
flag() |
||||||
|
} |
||||||
|
) |
||||||
|
} else { |
||||||
|
pointerInput(open, flag, seek) { |
||||||
|
awaitPointerEventScope { |
||||||
|
while (true) { |
||||||
|
val event = awaitPointerEvent(PointerEventPass.Main) |
||||||
|
with(event) { |
||||||
|
if (type == PointerEventType.Press) { |
||||||
|
// TODO does not work yet, all events are of Unknown type ( |
||||||
|
val lmb = buttons.isPrimaryPressed |
||||||
|
val rmb = buttons.isSecondaryPressed |
||||||
|
|
||||||
if (lmb && !rmb) { |
if (lmb && !rmb) { |
||||||
if (keyboardModifiers.isShiftPressed) { |
if (keyboardModifiers.isShiftPressed) { |
||||||
seek() |
seek() |
||||||
} else { |
} else { |
||||||
open() |
open() |
||||||
|
} |
||||||
|
} else if (rmb && !lmb) { |
||||||
|
flag() |
||||||
} |
} |
||||||
} else if (rmb && !lmb) { |
|
||||||
flag() |
|
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
Before Width: | Height: | Size: 896 B After Width: | Height: | Size: 896 B |
Before Width: | Height: | Size: 780 B After Width: | Height: | Size: 780 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Loading…
Reference in new issue