use std::sync::Arc;
use jni::errors::Result as JniResult;
use jni::objects::JString;
use jni::signature::{MethodSignature, RuntimeMethodSignature};
use jni::sys::jlong;
use crate::state::AppState;
use crate::jni_static;
pub(crate) fn request_image_picker(state: &Arc<AppState>, request_id: u64, dest_path: &str, title: &str) -> bool {
{
let picker = crate::state::IMAGE_PICKER.lock().unwrap();
if picker.open {
return false;
}
}
let vm = state.java_vm.lock().unwrap().clone();
let class_guard = state.egui_class.lock().unwrap();
let (Some(vm), Some(class)) = (vm, class_guard.as_ref()) else {
log::error!("JVM/class not initialized, cannot pick image");
return false;
};
let result = vm.attach_current_thread(|env| -> JniResult<()> {
let jdest = JString::from_str(env, dest_path)?;
let jtitle = JString::from_str(env, title)?;
let args = [
jni::objects::JValue::Long(request_id as jlong),
jni::objects::JValue::Object(&*jdest),
jni::objects::JValue::Object(&*jtitle),
];
let runtime_sig = RuntimeMethodSignature::from_str(
"(JLjava/lang/String;Ljava/lang/String;)V",
)?;
let sig = MethodSignature::from(&runtime_sig);
env.call_static_method(class, jni_static("pickImage"), sig, &args)?;
Ok(())
});
match result {
Ok(()) => {
crate::state::IMAGE_PICKER.lock().unwrap().open = true;
true
}
Err(e) => {
log::error!("failed to call Kotlin pickImage: {e}");
false
}
}
}
pub(crate) fn maybe_request_native_editor(state: &Arc<AppState>) {
let request = {
let mut bridge = crate::state::TEXT_BRIDGE.lock().unwrap();
if bridge.dialog_open {
return;
}
bridge.pending_request.take()
};
let Some(request) = request else {
return;
};
let vm = state.java_vm.lock().unwrap().clone();
let class_guard = state.egui_class.lock().unwrap();
if let (Some(vm), Some(class)) = (vm, class_guard.as_ref()) {
let result = vm.attach_current_thread(|env| -> JniResult<()> {
let jstr = JString::from_str(env, &request.initial_text)?;
let jtitle = JString::from_str(env, &request.title)?;
let jhint = JString::from_str(env, &request.hint)?;
let args = [
jni::objects::JValue::Long(request.widget_id as jlong),
jni::objects::JValue::Object(&*jstr),
jni::objects::JValue::Object(&*jtitle),
jni::objects::JValue::Object(&*jhint),
jni::objects::JValue::Int(request.input_type),
];
let runtime_sig = RuntimeMethodSignature::from_str(
"(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V",
)?;
let sig = MethodSignature::from(&runtime_sig);
env.call_static_method(
class,
jni_static("showNativeTextEditor"),
sig,
&args,
)?;
Ok(())
});
if let Err(e) = result {
log::error!("failed to call Kotlin showNativeTextEditor: {e}");
} else {
crate::state::TEXT_BRIDGE.lock().unwrap().dialog_open = true;
state.push_extra_event(egui::Event::Key {
key: egui::Key::Escape,
physical_key: None,
pressed: true,
repeat: false,
modifiers: egui::Modifiers::default(),
});
}
} else {
log::error!("JVM/class not initialized, cannot show native editor");
}
}