8 Commits
Author SHA1 Message Date
izzy2lostandGitHub 5ad3f98ee6 Add files via upload 2025-06-12 22:45:10 -04:00
Robert Kirkman d11c66eea9 special external storage permission
- bump SDL to 2.32.0
    - bump NDK to r27c
    - bump AGP to 8.8.0
    - bump Gradle to 8.10.2
    - bump CMake to 3.31.5
    - bump targetSdkVersion to 34
    - add GitHub Actions Release support (Debug)
    - add Special External Storage Permission support
    - fix "assets not found" error on first launch
    - add Android 5 & 6 support
2025-02-19 18:58:13 -06:00
WaterdishandGitHub d6c503f0e9 Update README.md 2024-12-06 21:15:54 -08:00
WaterdishandGitHub e9a5064e59 Update README.md 2024-11-25 21:06:20 -08:00
Waterdish 821dd700ff Fix free look not working with controllers 2024-11-23 22:58:07 -08:00
Waterdish ef7780ffaa Better c-button fix 2024-11-23 20:07:55 -08:00
Waterdish 4ee3f23df8 Fix c buttons not having a default binding 2024-11-23 19:24:23 -08:00
Waterdish cb1378429f Touch Controls 2024-11-23 18:45:19 -08:00
32 changed files with 1131 additions and 191 deletions
+74
View File
@@ -0,0 +1,74 @@
name: generate-android-apk
on:
workflow_dispatch:
jobs:
generate-2ship-otr:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ninja-build cmake g++ gcc libzip-dev zipcmp zipmerge ziptool
- name: Install latest SDL
run: |
if [ ! -d "SDL2-2.28.5" ]; then
wget https://github.com/libsdl-org/SDL/releases/download/release-2.28.5/SDL2-2.28.5.tar.gz
tar -xzf SDL2-2.28.5.tar.gz
fi
cd SDL2-2.28.5
./configure --enable-hidapi-libusb
make -j 10
sudo make install
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
- name: Install latest tinyxml2
run: |
sudo apt-get remove libtinyxml2-dev
if [ ! -d "tinyxml2-10.0.0" ]; then
wget https://github.com/leethomason/tinyxml2/archive/refs/tags/10.0.0.tar.gz
tar -xzf 10.0.0.tar.gz
fi
cd tinyxml2-10.0.0
mkdir -p build
cd build
cmake ..
make
sudo make install
- name: Generate 2ship.o2r
run: |
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release
cmake --build build-cmake --config Release --target Generate2ShipOtr -j3
- uses: actions/upload-artifact@v4
with:
name: 2ship.o2r
path: 2ship.o2r
retention-days: 1
build-android:
needs: generate-2ship-otr
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install dependencies
run: sudo apt-get install -y ninja-build
- name: Download 2ship.o2r
uses: actions/download-artifact@v4
with:
name: 2ship.o2r
path: Android/app/src/main/assets
- name: Build 2Ship APK
run: |
cd Android/
./gradlew assembleDebug -P elfBuildType=RelWithDebInfo
mv app/build/outputs/apk/debug/app-debug.apk ../2ship.apk
- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: 2ship-apk
path: 2ship.apk
+29 -2
View File
@@ -1,7 +1,8 @@
name: generate-builds
on:
push:
pull_request:
# push:
# pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
@@ -380,3 +381,29 @@ jobs:
with:
name: 2ship-windows
path: 2ship-windows
build-android:
needs: generate-2ship-otr
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install dependencies
run: sudo apt-get install -y ninja-build
- name: Download 2ship.o2r
uses: actions/download-artifact@v4
with:
name: 2ship.o2r
path: Android/app/src/main/assets
- name: Build 2Ship
run: |
cd Android/
./gradlew assembleDebug -P elfBuildType=RelWithDebInfo
mv app/build/outputs/apk/debug/app-debug.apk ../2ship.apk
- name: Create release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.ref }}
file: 2ship.apk
+3
View File
@@ -67,3 +67,6 @@ _packages/
/mm/src/boot/build.c
/mm/windows/properties.h
/clang-format.exe
# IntelliJ / Android Studio
.idea
+1 -1
View File
@@ -1,6 +1,6 @@
[submodule "libultraship"]
path = libultraship
url = https://github.com/Waterdish/libultraship.git
url = https://github.com/robertkirkman/libultraship.git
[submodule "OTRExporter"]
path = OTRExporter
url = https://github.com/Waterdish/OTRExporter.git
+23 -25
View File
@@ -1,4 +1,4 @@
def buildAsLibrary = project.hasProperty('BUILD_AS_LIBRARY');
def buildAsLibrary = project.hasProperty('BUILD_AS_LIBRARY')
def buildAsApplication = !buildAsLibrary
if (buildAsApplication) {
apply plugin: 'com.android.application'
@@ -8,25 +8,21 @@ else {
}
android {
ndkPath "/home/waterdish/Android/Sdk/ndk/26.0.10792818" // Point to your own NDK
compileSdkVersion 31
ndkVersion '27.2.12479018'
compileSdkVersion 34
defaultConfig {
if (buildAsApplication) {
applicationId "com.dishii.mm"
}
minSdkVersion 24
targetSdkVersion 31
minSdkVersion 21
//noinspection OldTargetApi
targetSdkVersion 34
versionCode 4
versionName "1.1.1"
externalNativeBuild {
//ndkBuild {
// arguments "APP_PLATFORM=android-23"
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
//}
cmake {
arguments "-DSDL_SHARED=ON", "-DANDROID_STL=c++_static", "-DHAVE_LD_VERSION_SCRIPT=OFF",'-DUSE_OPENGLES=ON'
arguments "-DANDROID_APPNAME=${applicationId}", "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static", "-DHAVE_LD_VERSION_SCRIPT=OFF", "-DUSE_OPENGLES=ON", "-DCMAKE_BUILD_TYPE=$elfBuildType"
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
//abiFilters 'arm64-v8a'
}
}
}
@@ -34,9 +30,17 @@ android {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
applicationVariants.all { variant ->
buildFeatures {
buildConfig = true
}
namespace 'com.dishii.mm'
lint {
abortOnError false
}
applicationVariants.configureEach { variant ->
tasks["merge${variant.name.capitalize()}Assets"]
.dependsOn("externalNativeBuild${variant.name.capitalize()}")
}
@@ -45,26 +49,20 @@ android {
jniLibs.srcDir 'libs'
}
externalNativeBuild {
//ndkBuild {
// path 'jni/Android.mk'
//}
cmake {
path '../../CMakeLists.txt'
version "3.25.1"
version "3.31.5"
}
}
}
lintOptions {
abortOnError false
}
if (buildAsLibrary) {
libraryVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith(".aar")) {
def fileName = "org.libsdl.app.aar";
def fileName = "com.dishii.mm.aar"
output.outputFile = new File(outputFile.parent, fileName);
}
}
@@ -74,13 +72,13 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.core:core:1.7.0' // Use the latest version
implementation 'androidx.core:core:1.13.1'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
}
task wrapper(type: Wrapper) {
gradleVersion = '7.0.3'
tasks.register('wrapper', Wrapper) {
gradleVersion = '8.10.2'
}
task prepareKotlinBuildScriptModel {
tasks.register('prepareKotlinBuildScriptModel') {
}
Binary file not shown.
-5
View File
@@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+3 -4
View File
@@ -3,7 +3,6 @@
com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dishii.mm"
android:versionCode="4"
android:versionName="1.1.1"
android:installLocation="auto">
@@ -54,8 +53,8 @@
<!-- Allow access to the vibrator -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!-- if you want to capture audio, uncomment this. -->
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
@@ -73,7 +72,8 @@
android:allowBackup="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true"
android:appCategory="game" >
android:appCategory="game"
android:requestLegacyExternalStorage="true">
<!-- Example of setting SDL hints from AndroidManifest.xml:
@@ -84,7 +84,6 @@
<activity android:name="MainActivity"
android:label="@string/app_name"
android:alwaysRetainTaskState="true"
android:launchMode="singleInstance"
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
+1
View File
@@ -1,2 +1,3 @@
# Extractor Assets Copied by CMake during buildtime
assets/
mods/
@@ -2,6 +2,8 @@ package com.dishii.mm;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -9,53 +11,70 @@ import java.io.InputStream;
import java.io.OutputStream;
public class AssetCopyUtil {
// based on https://stackoverflow.com/a/8366081/11708026
// This is desirable because it bulk copies all assets indiscriminately, simplifying the code in MainActivity
// the side effect is that, some people will see strange, unidentifiable files appearing in their destination folder.
// those extra files do not come from the app itself. They originate from something inside the Android ROM
// of the device they are using, and can be observed to vary between different models of devices.
public static void copyAssetsToExternal(Context context, String externalFolderPath) {
externalFolderPath = externalFolderPath + "/";
copyFileOrDir(context, "", externalFolderPath); // copy all files in assets folder to the destination
}
public static void copyAssetsToExternal(Context context, String assetsFolderPath, String externalFolderPath) throws IOException {
private static void copyFileOrDir(Context context, String srcpath, String destpath) {
AssetManager assetManager = context.getAssets();
String[] assetFiles = assetManager.list(assetsFolderPath);
for (String assetFile : assetFiles) {
String assetPath = assetsFolderPath + File.separator + assetFile;
String externalPath = externalFolderPath + File.separator + assetFile;
if (assetManager.list(assetPath).length > 0) {
// It's a directory
// Check if the directory exists in the external storage
File externalDir = new File(externalPath);
if (!externalDir.exists()) {
externalDir.mkdirs(); // Create the directory if it doesn't exist
}
// Recursively copy contents of the directory
copyAssetsToExternal(context, assetPath, externalPath);
String assets[] = null;
String tag = "AssetCopyUtil";
try {
Log.i(tag, "copyFileOrDir() " + srcpath);
assets = assetManager.list(srcpath);
if (assets.length == 0) {
copyFile(context, srcpath, destpath);
} else {
// It's a file
File externalFile = new File(externalPath);
if (!externalFile.exists()) {
// Check if the file exists in the external storage
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(assetPath);
out = new FileOutputStream(externalPath);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
String fullPath = destpath + srcpath;
Log.i(tag, "path=" + fullPath);
File dir = new File(fullPath);
if (!dir.exists())
if (!dir.mkdirs())
Log.i(tag, "could not create dir " + fullPath);
for (int i = 0; i < assets.length; ++i) {
String p;
if (srcpath.isEmpty())
p = "";
else
p = srcpath + "/";
copyFileOrDir(context,p + assets[i], destpath);
}
}
} catch (IOException ex) {
Log.e(tag, "I/O Exception", ex);
}
}
private static void copyFile(Context context, String filename, String destpath) {
AssetManager assetManager = context.getAssets();
InputStream in = null;
OutputStream out = null;
String newFileName = null;
String tag = "AssetCopyUtil";
try {
Log.i(tag, "copyFile() " + filename);
in = assetManager.open(filename);
newFileName = destpath + filename;
out = new FileOutputStream(newFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e(tag, "Exception in copyFile() of " + newFileName);
Log.e(tag, "Exception in copyFile() " + e.toString());
}
}
}
@@ -0,0 +1,26 @@
package com.dishii.mm;
public class ControllerButtons {
// Xbox Buttons
public static final int BUTTON_A = 0;
public static final int BUTTON_B = 1;
public static final int BUTTON_X = 2;
public static final int BUTTON_Y = 3;
public static final int BUTTON_LB = 9; // Left Bumper
public static final int BUTTON_RB = -5; // Right Bumper
public static final int BUTTON_BACK = 4;
public static final int BUTTON_START = 6;
public static final int BUTTON_DPAD_UP = 11;
public static final int BUTTON_DPAD_DOWN = 12;
public static final int BUTTON_DPAD_LEFT = 13;
public static final int BUTTON_DPAD_RIGHT = 14;
// Xbox Axis (Joysticks and Triggers)
public static final int AXIS_LX = 0; // Left stick X
public static final int AXIS_LY = 1; // Left stick Y
public static final int AXIS_RX = 2; // Right stick X
public static final int AXIS_RY = 3; // Right stick Y
public static final int AXIS_LT = -2; // Left Trigger (negative axis)
public static final int AXIS_RT = -4; // Right Trigger (negative axis)
}
File diff suppressed because it is too large Load Diff
@@ -60,8 +60,8 @@ import java.util.Locale;
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 30;
private static final int SDL_MICRO_VERSION = 5;
private static final int SDL_MINOR_VERSION = 32;
private static final int SDL_MICRO_VERSION = 0;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
@@ -89,7 +89,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
| InputDevice.SOURCE_CLASS_POSITION
| InputDevice.SOURCE_CLASS_TRACKBALL);
if (s2 != 0) cls += "Some_Unkown";
if (s2 != 0) cls += "Some_Unknown";
s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
@@ -163,7 +163,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (s == FLAG_TAINTED) src += " FLAG_TAINTED";
s2 &= ~FLAG_TAINTED;
if (s2 != 0) src += " Some_Unkown";
if (s2 != 0) src += " Some_Unknown";
Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src);
}
@@ -274,7 +274,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// "SDL2_mixer",
// "SDL2_net",
// "SDL2_ttf",
"2ship"
"main"
};
}
@@ -790,6 +790,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
SDLActivity.mFullscreenModeActive = false;
}
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
}
} else {
Log.e(TAG, "error handling message, getContext() returned no Activity");
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed state -->
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="#10FFFFFF" /> <!-- Darker color when pressed -->
<stroke
android:width="2.5dp"
android:color="#20FFFFFF" />
</shape>
</item>
<!-- Default state -->
<item>
<shape android:shape="oval">
<solid android:color="#20FFFFFF" />
<stroke
android:width="2.5dp"
android:color="#25FFFFFF" />
</shape>
</item>
</selector>
@@ -0,0 +1,19 @@
<vector android:alpha="1.0" android:height="221.78dp"
android:viewportHeight="221.78" android:viewportWidth="221.78"
android:width="221.78dp"
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="1.0"
android:fillColor="#20FFFFFF"
android:pathData="M221.78,87.07v47.64a11.53,11.53 0,0 1,-11.5 11.5H151.62a5.42,5.42 0,0 0,-5.41 5.41v58.66a11.53,11.53 0,0 1,-11.5 11.5H87.07a11.53,11.53 0,0 1,-11.5 -11.5V151.61a5.41,5.41 0,0 0,-5.41 -5.41H11.5A11.53,11.53 0,0 1,0 134.7V87.05a11.53,11.53 0,0 1,11.5 -11.5H70.16a5.41,5.41 0,0 0,5.41 -5.41V11.5A11.53,11.53 0,0 1,87.07 0h47.64a11.53,11.53 0,0 1,11.5 11.5V70.16a5.41,5.41 0,0 0,5.41 5.41h58.66A11.53,11.53 0,0 1,221.78 87.07Z"
android:strokeWidth="2.5"
android:strokeColor="#25FFFFFF"
android:strokeAlpha="1.0" />
<path android:fillColor="#25FFFFFF" android:fillAlpha="1.0"
android:pathData="M195.47,110.32l-16.26,-9.38a0.65,0.65 0,0 0,-1 0.56v18.78a0.66,0.66 0,0 0,1 0.57l16.26,-9.39A0.66,0.66 0,0 0,195.47 110.32Z" />
<path android:fillColor="#25FFFFFF" android:fillAlpha="1.0"
android:pathData="M26.31,110.32l16.26,-9.38a0.65,0.65 0,0 1,1 0.56v18.78a0.66,0.66 0,0 1,-1 0.57l-16.26,-9.39A0.66,0.66 0,0 1,26.31 110.32Z" />
<path android:fillColor="#25FFFFFF" android:fillAlpha="1.0"
android:pathData="M110.32,26.31l-9.38,16.26a0.65,0.65 0,0 0,0.56 1h18.78a0.66,0.66 0,0 0,0.57 -1l-9.39,-16.26A0.66,0.66 0,0 0,110.32 26.31Z" />
<path android:fillColor="#25FFFFFF" android:fillAlpha="1.0"
android:pathData="M110.32,195.47l-9.38,-16.26a0.65,0.65 0,0 1,0.56 -1h18.78a0.66,0.66 0,0 1,0.57 1l-9.39,16.26A0.66,0.66 0,0 1,110.32 195.47Z" />
</vector>
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed state -->
<item android:state_pressed="true">
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#10FFFFFF" /> <!-- Darker color when pressed -->
<stroke
android:width="2dp"
android:color="#25FFFFFF" />
<size
android:width="25dp"
android:height="25dp" />
<corners android:radius="10dp" />
</shape>
</item>
</layer-list>
</item>
<!-- Default state -->
<item>
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#20FFFFFF" /> <!-- Default color -->
<stroke
android:width="2dp"
android:color="#25FFFFFF" />
<size
android:width="25dp"
android:height="25dp" />
<corners android:radius="10dp" />
</shape>
</item>
</layer-list>
</item>
</selector>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#20FFFFFF"
android:pathData="M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z" />
</vector>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="#10FFFFFF" />
<stroke
android:width="2dp"
android:color="#25FFFFFF" />
<size
android:width="25dp"
android:height="25dp" />
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
</shape>
</item>
<item>
<shape android:shape="oval">
<solid android:color="#30000000" />
<size
android:width="30dp"
android:height="30dp" />
</shape>
</item>
</layer-list>
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed state -->
<item android:state_pressed="true">
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#10FFFFFF" /> <!-- Darker color when pressed -->
<stroke
android:width="2dp"
android:color="#25FFFFFF" />
<size
android:width="25dp"
android:height="25dp" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="50dp"
android:topRightRadius="10dp" />
</shape>
</item>
</layer-list>
</item>
<!-- Default state -->
<item>
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#20FFFFFF" /> <!-- Default color -->
<stroke
android:width="2dp"
android:color="#25FFFFFF" />
<size
android:width="25dp"
android:height="25dp" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="50dp"
android:topRightRadius="10dp" />
</shape>
</item>
</layer-list>
</item>
</selector>
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed state -->
<item android:state_pressed="true">
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#10FFFFFF" /> <!-- Darker color when pressed -->
<stroke
android:width="2dp"
android:color="#25FFFFFF" />
<size
android:width="25dp"
android:height="25dp" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="50dp" />
</shape>
</item>
</layer-list>
</item>
<!-- Default state -->
<item>
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#20FFFFFF" /> <!-- Default color -->
<stroke
android:width="2dp"
android:color="#25FFFFFF" />
<size
android:width="25dp"
android:height="25dp" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="50dp" />
</shape>
</item>
</layer-list>
</item>
</selector>

Some files were not shown because too many files have changed in this diff Show More