Add a context menu button.

This commit is contained in:
TÖRÖK Attila 2023-06-18 00:47:43 +02:00
parent 0a894f47e7
commit ecbfe96c22
3 changed files with 90 additions and 8 deletions

View File

@ -6,6 +6,7 @@ import com.google.androidgamesdk.GameActivity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.Window;
@ -23,6 +24,7 @@ import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.view.View;
import android.widget.Button;
import android.widget.PopupMenu;
import java.util.ArrayList;
import java.util.List;
@ -58,6 +60,9 @@ public class FullscreenNativeActivity extends GameActivity {
private static native void resized();
private static native String[] prepareContextMenu();
private static native void runContextMenuCallback(int index);
private static native void clearContextMenu();
private static <T> List<T> gatherAllDescendantsOfType(View v, Class t) {
List<T> result = new ArrayList<T>();
@ -110,6 +115,24 @@ public class FullscreenNativeActivity extends GameActivity {
}
}
}
else if ("cm".equals(tag)) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
String[] items = prepareContextMenu();
PopupMenu popup = new PopupMenu(this, b);
for (int i = 0; i < items.length; ++i) {
popup.getMenu().add(Menu.NONE, i, Menu.NONE, items[i]);
}
popup.setOnMenuItemClickListener((item) -> {
runContextMenuCallback(item.getItemId());
return true;
});
popup.setOnDismissListener((pm) -> {
clearContextMenu();
});
popup.show();
}
}
else if (tag != null) {
String[] spl = tag.split(" ", 2);
byte by = Byte.parseByte(spl[0]);

View File

@ -17,8 +17,9 @@
<LinearLayout
android:id="@+id/keyboard"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="64dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@ -404,20 +405,26 @@
<LinearLayout
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="64dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/keyboard">
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/button_kb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:tag="kb"
android:text="⌨️" />
android:text="⌨" />
<Button
android:id="@+id/button_cm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:tag="cm"
android:text="▤" />
</LinearLayout>

View File

@ -2,8 +2,8 @@ mod audio;
mod keycodes;
use jni::{
objects::{JByteArray, JClass, JIntArray, JObject, ReleaseMode},
sys::{jbyte, jchar, JNIEnv},
objects::{JByteArray, JClass, JIntArray, JObject, JObjectArray, ReleaseMode, JString},
sys::{jbyte, jchar, jint, jarray, jobject}, JNIEnv
};
use std::{
sync::{Arc, Mutex},
@ -378,6 +378,58 @@ fn get_jvm<'a>() -> Result<(jni::JavaVM, JObject<'a>), Box<dyn std::error::Error
return Ok((vm, activity));
}
#[no_mangle]
pub unsafe extern "C" fn Java_rs_ruffle_FullscreenNativeActivity_prepareContextMenu(
mut env: JNIEnv,
_class: JClass,
) -> jobject
{
log::warn!("preparing context menu!");
if let Some(player) = unsafe { playerbox.as_ref() } {
if let Ok(mut player_lock) = player.lock() {
let items = player_lock.prepare_context_menu();
let mut arr = env.new_object_array(items.len() as i32, "java/lang/String", JObject::null()).unwrap();
for (i, e) in items.iter().enumerate() {
let s = env.new_string(&e.caption).unwrap();
env.set_object_array_element(&arr, i as i32, s);
}
return arr.as_raw();
}
}
return JObject::null().into_raw();
}
#[no_mangle]
pub unsafe extern "C" fn Java_rs_ruffle_FullscreenNativeActivity_runContextMenuCallback(
_env: JNIEnv,
_class: JClass,
index: jint,
)
{
if let Some(player) = unsafe { playerbox.as_ref() } {
if let Ok(mut player_lock) = player.lock() {
player_lock.run_context_menu_callback(index as usize);
}
}
}
#[no_mangle]
pub unsafe extern "C" fn Java_rs_ruffle_FullscreenNativeActivity_clearContextMenu(
_env: JNIEnv,
_class: JClass,
)
{
if let Some(player) = unsafe { playerbox.as_ref() } {
if let Ok(mut player_lock) = player.lock() {
player_lock.clear_custom_menu_items();
}
}
}
fn get_swf_bytes() -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let (jvm, activity) = get_jvm()?;
let mut env = jvm.attach_current_thread()?;