forked from MeloNX/MeloNX
add bottom popup ingame
This commit is contained in:
parent
0bf93ef754
commit
8c0bd460d9
@ -36,6 +36,7 @@ android {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
@ -92,6 +93,7 @@ dependencies {
|
||||
implementation "androidx.preference:preference-ktx:1.2.0"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2'
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
implementation("br.com.devsrsouza.compose.icons:css-gg:1.1.0")
|
||||
implementation "io.coil-kt:coil-compose:2.4.0"
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
|
@ -46,15 +46,17 @@ class GameController(var activity: Activity) {
|
||||
return view
|
||||
}
|
||||
@Composable
|
||||
fun Compose(viewModel: MainViewModel) : Unit
|
||||
{
|
||||
fun Compose(viewModel: MainViewModel) : Unit {
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxSize(), factory = { context ->
|
||||
val controller = GameController(viewModel.activity)
|
||||
val c = Create(context, viewModel.activity, controller)
|
||||
viewModel.activity.lifecycleScope.apply {
|
||||
viewModel.activity.lifecycleScope.launch {
|
||||
val events = merge(controller.leftGamePad.events(),controller.rightGamePad.events())
|
||||
viewModel.activity.lifecycleScope.apply {
|
||||
viewModel.activity.lifecycleScope.launch {
|
||||
val events = merge(
|
||||
controller.leftGamePad.events(),
|
||||
controller.rightGamePad.events()
|
||||
)
|
||||
.shareIn(viewModel.activity.lifecycleScope, SharingStarted.Lazily)
|
||||
events.safeCollect {
|
||||
controller.handleEvent(it)
|
||||
|
@ -1,8 +1,14 @@
|
||||
package org.ryujinx.android
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.PathFillType
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
@ -10,13 +16,17 @@ import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.graphics.StrokeJoin
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.path
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import compose.icons.CssGgIcons
|
||||
import compose.icons.cssggicons.Games
|
||||
|
||||
class Icons {
|
||||
companion object{
|
||||
/// Icons exported from https://www.composables.com/icons
|
||||
@Composable
|
||||
fun Download(): ImageVector {
|
||||
fun download(): ImageVector {
|
||||
val primaryColor = MaterialTheme.colorScheme.primary
|
||||
return remember {
|
||||
ImageVector.Builder(
|
||||
name = "download",
|
||||
@ -26,9 +36,9 @@ class Icons {
|
||||
viewportHeight = 40.0f
|
||||
).apply {
|
||||
path(
|
||||
fill = SolidColor(Color.Black),
|
||||
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
|
||||
stroke = SolidColor(primaryColor),
|
||||
fillAlpha = 1f,
|
||||
stroke = null,
|
||||
strokeAlpha = 1f,
|
||||
strokeLineWidth = 1.0f,
|
||||
strokeLineCap = StrokeCap.Butt,
|
||||
@ -84,7 +94,77 @@ class Icons {
|
||||
}
|
||||
}
|
||||
@Composable
|
||||
fun VideoGame(): ImageVector {
|
||||
fun vSync(): ImageVector {
|
||||
val primaryColor = MaterialTheme.colorScheme.primary
|
||||
return remember {
|
||||
ImageVector.Builder(
|
||||
name = "60fps",
|
||||
defaultWidth = 40.0.dp,
|
||||
defaultHeight = 40.0.dp,
|
||||
viewportWidth = 40.0f,
|
||||
viewportHeight = 40.0f
|
||||
).apply {
|
||||
path(
|
||||
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
|
||||
stroke = SolidColor(primaryColor),
|
||||
fillAlpha = 1f,
|
||||
strokeAlpha = 1f,
|
||||
strokeLineWidth = 1.0f,
|
||||
strokeLineCap = StrokeCap.Butt,
|
||||
strokeLineJoin = StrokeJoin.Miter,
|
||||
strokeLineMiter = 1f,
|
||||
pathFillType = PathFillType.NonZero
|
||||
) {
|
||||
moveTo(7.292f, 31.458f)
|
||||
quadToRelative(-1.542f, 0f, -2.625f, -1.041f)
|
||||
quadToRelative(-1.084f, -1.042f, -1.084f, -2.625f)
|
||||
verticalLineTo(12.208f)
|
||||
quadToRelative(0f, -1.583f, 1.084f, -2.625f)
|
||||
quadTo(5.75f, 8.542f, 7.292f, 8.542f)
|
||||
horizontalLineTo(14f)
|
||||
quadToRelative(0.75f, 0f, 1.292f, 0.541f)
|
||||
quadToRelative(0.541f, 0.542f, 0.541f, 1.292f)
|
||||
reflectiveQuadToRelative(-0.541f, 1.292f)
|
||||
quadToRelative(-0.542f, 0.541f, -1.292f, 0.541f)
|
||||
horizontalLineTo(7.208f)
|
||||
verticalLineToRelative(5.084f)
|
||||
horizontalLineToRelative(6.709f)
|
||||
quadToRelative(1.541f, 0f, 2.583f, 1.041f)
|
||||
quadToRelative(1.042f, 1.042f, 1.042f, 2.625f)
|
||||
verticalLineToRelative(6.834f)
|
||||
quadToRelative(0f, 1.583f, -1.042f, 2.625f)
|
||||
quadToRelative(-1.042f, 1.041f, -2.583f, 1.041f)
|
||||
close()
|
||||
moveToRelative(-0.084f, -10.5f)
|
||||
verticalLineToRelative(6.834f)
|
||||
horizontalLineToRelative(6.709f)
|
||||
verticalLineToRelative(-6.834f)
|
||||
close()
|
||||
moveToRelative(17.125f, 6.834f)
|
||||
horizontalLineToRelative(8.459f)
|
||||
verticalLineTo(12.208f)
|
||||
horizontalLineToRelative(-8.459f)
|
||||
verticalLineToRelative(15.584f)
|
||||
close()
|
||||
moveToRelative(0f, 3.666f)
|
||||
quadToRelative(-1.541f, 0f, -2.583f, -1.041f)
|
||||
quadToRelative(-1.042f, -1.042f, -1.042f, -2.625f)
|
||||
verticalLineTo(12.208f)
|
||||
quadToRelative(0f, -1.583f, 1.042f, -2.625f)
|
||||
quadToRelative(1.042f, -1.041f, 2.583f, -1.041f)
|
||||
horizontalLineToRelative(8.459f)
|
||||
quadToRelative(1.541f, 0f, 2.583f, 1.041f)
|
||||
quadToRelative(1.042f, 1.042f, 1.042f, 2.625f)
|
||||
verticalLineToRelative(15.584f)
|
||||
quadToRelative(0f, 1.583f, -1.042f, 2.625f)
|
||||
quadToRelative(-1.042f, 1.041f, -2.583f, 1.041f)
|
||||
close()
|
||||
}
|
||||
}.build()
|
||||
}
|
||||
}
|
||||
@Composable
|
||||
fun videoGame(): ImageVector {
|
||||
val primaryColor = MaterialTheme.colorScheme.primary
|
||||
return remember {
|
||||
ImageVector.Builder(
|
||||
@ -96,8 +176,8 @@ class Icons {
|
||||
).apply {
|
||||
path(
|
||||
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
|
||||
fillAlpha = 1f,
|
||||
stroke = SolidColor(primaryColor),
|
||||
fillAlpha = 1f,
|
||||
strokeAlpha = 1f,
|
||||
strokeLineWidth = 1.0f,
|
||||
strokeLineCap = StrokeCap.Butt,
|
||||
@ -180,3 +260,15 @@ class Icons {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun Preview(){
|
||||
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = CssGgIcons.Games,
|
||||
contentDescription = "Open Panel"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -228,6 +228,7 @@ class HomeViews {
|
||||
mutableStateListOf<GameModel>()
|
||||
}
|
||||
|
||||
|
||||
if(refresh.value) {
|
||||
viewModel.setViewList(list)
|
||||
refresh.value = false
|
||||
@ -342,7 +343,7 @@ class HomeViews {
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Icon(
|
||||
imageVector = org.ryujinx.android.Icons.Download(),
|
||||
imageVector = org.ryujinx.android.Icons.download(),
|
||||
contentDescription = "Game Dlc",
|
||||
tint = Color.Green,
|
||||
modifier = Modifier
|
||||
|
@ -25,24 +25,22 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.PathFillType
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.graphics.StrokeJoin
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.path
|
||||
import androidx.compose.ui.input.pointer.PointerEventType
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.compose.ui.window.Popup
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import compose.icons.CssGgIcons
|
||||
import compose.icons.cssggicons.ToolbarBottom
|
||||
import org.ryujinx.android.GameController
|
||||
import org.ryujinx.android.GameHost
|
||||
import org.ryujinx.android.Icons
|
||||
import org.ryujinx.android.RyujinxNative
|
||||
import org.ryujinx.android.viewmodels.MainViewModel
|
||||
import org.ryujinx.android.viewmodels.QuickSettings
|
||||
import org.ryujinx.android.viewmodels.SettingsViewModel
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -88,6 +86,16 @@ class MainView {
|
||||
|
||||
val ryujinxNative = RyujinxNative()
|
||||
|
||||
var showController = remember {
|
||||
mutableStateOf(QuickSettings(mainViewModel.activity).useVirtualController)
|
||||
}
|
||||
var enableVsync = remember {
|
||||
mutableStateOf(QuickSettings(mainViewModel.activity).enableVsync)
|
||||
}
|
||||
var showMore = remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
// touch surface
|
||||
Surface(color = Color.Transparent, modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@ -95,8 +103,9 @@ class MainView {
|
||||
.pointerInput(Unit) {
|
||||
awaitPointerEventScope {
|
||||
while (true) {
|
||||
Thread.sleep(2)
|
||||
val event = awaitPointerEvent()
|
||||
if (!showController.value)
|
||||
continue
|
||||
|
||||
val change = event
|
||||
.component1()
|
||||
@ -137,15 +146,46 @@ class MainView {
|
||||
.padding(8.dp)
|
||||
) {
|
||||
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||
mainViewModel.controller?.setVisible(!mainViewModel.controller!!.isVisible)
|
||||
showMore.value = true
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = Icons.VideoGame(),
|
||||
contentDescription = "Toggle Virtual Pad"
|
||||
imageVector = CssGgIcons.ToolbarBottom,
|
||||
contentDescription = "Open Panel"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if(showMore.value){
|
||||
Popup(alignment = Alignment.BottomCenter, onDismissRequest = {showMore.value = false}) {
|
||||
Surface(modifier = Modifier.padding(16.dp),
|
||||
shape = MaterialTheme.shapes.medium) {
|
||||
Row(modifier = Modifier.padding(8.dp)) {
|
||||
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||
showMore.value = false
|
||||
showController.value = !showController.value
|
||||
mainViewModel.controller?.setVisible(showController.value)
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = Icons.videoGame(),
|
||||
contentDescription = "Toggle Virtual Pad"
|
||||
)
|
||||
}
|
||||
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||
showMore.value = false
|
||||
enableVsync.value = !enableVsync.value
|
||||
RyujinxNative().graphicsRendererSetVsync(enableVsync.value)
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = Icons.vSync(),
|
||||
tint = if(enableVsync.value) Color.Green else Color.Red,
|
||||
contentDescription = "Toggle VSync"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var showBackNotice = remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ pluginManagement {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven { url 'https://jitpack.io' }
|
||||
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
@ -12,6 +13,7 @@ dependencyResolutionManagement {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
|
||||
}
|
||||
}
|
||||
rootProject.name = "RyujinxAndroid"
|
||||
|
Loading…
x
Reference in New Issue
Block a user