use jnim::*; use ndkm::Window as ANWin; use crate::android; use crate::app::bind_global_if_need; use android::view::SurfaceHolder as _; use super::{replace_anwin, with_win, with_win_mut, Key, WinKey, WinRef, WinTouch}; pub trait WinView: JNameMaker + JPlainMarker + AsRef + AsRef { const VIEW_NAME: &'static str; fn key(&self, env: &JEnv) -> Key; fn activity_on_create(&self, env: &JEnv, _saved_instance_state: Option<&android::os::Bundle>) { let activity: &android::view::View = self.as_ref(); let key = self.key(env); bind_global_if_need( env, activity .get_context(env) .map(|v| v.get_application_context(env)) .flatten() .map(|v| v.cast(env)) .flatten(), ); with_win_mut(key, |win| { let display_metrics = activity.get_resources(env)?.get_display_metrics(env)?; let scale_factor = display_metrics.r#density(env)?; win.scale_factor = Some(scale_factor); Some(()) }); with_win(key, |win| { win.delegate()?.on_create(win.win_ref()); Some(()) }); } fn activity_on_destroy(&self, env: &JEnv) { let key = self.key(env); with_win(key, |win| { win.delegate()?.on_destroy(win.win_ref()); Some(()) }); } extern "C" fn activity_on_start(env: &JEnv, this: &Self) { log::info!("activity_on_start"); let key = this.key(env); with_win(key, |win| { win.delegate()?.on_start(win.win_ref()); Some(()) }); } extern "C" fn activity_on_stop(env: &JEnv, this: &Self) { log::info!("activity_on_stop"); let key = this.key(env); with_win(key, |win| { win.delegate()?.on_stop(win.win_ref()); Some(()) }); } extern "C" fn activity_on_resume(_: &JEnv, _: &Self) { log::info!("activity_on_resume"); } extern "C" fn activity_on_pause(_: &JEnv, _: &Self) { log::info!("activity_on_pause"); } extern "C" fn surface_created(env: &JEnv, this: &Self, arg0: &android::view::SurfaceHolderObject) { log::error!("surface_created"); let key = this.key(env); if let Some(surface) = arg0.get_surface(env) { let anwin = ANWin::from_java(env.as_sys(), surface.as_sys()); replace_anwin(key, anwin); } with_win(key, |win| { win.delegate()?.on_resume(win.win_ref()); Some(()) }); } extern "C" fn surface_changed(env: &JEnv, this: &Self, arg0: &android::view::SurfaceHolderObject, _: JInt, arg2: JInt, arg3: JInt) { log::error!("surface_changed {arg2} {arg3}"); let key = this.key(env); let old = if let Some(surface) = arg0.get_surface(env) { let anwin = ANWin::from_java(env.as_sys(), surface.as_sys()); replace_anwin(key, anwin) } else { None }; with_win(key, |win| { if old.as_ref() != win.anwin() { // log::error!("on_pause on_resume"); if let Some(old) = &old { win.delegate()?.on_pause(WinRef(Some(old), win)); } win.delegate()?.on_resume(win.win_ref()); } else { // log::error!("on_resize"); win.delegate()?.on_resize(win.win_ref(), (arg2 as _, arg3 as _)); } Some(()) }); } extern "C" fn surface_destroyed(env: &JEnv, this: &Self, _: &android::view::SurfaceHolderObject) { log::error!("surface_destroyed"); let key = this.key(env); let old = replace_anwin(key, None); with_win(key, |win| { win.delegate()?.on_pause(WinRef(old.as_ref(), win)); Some(()) }); } extern "C" fn surface_redraw_needed(env: &JEnv, this: &Self, _: &android::view::SurfaceHolderObject) { log::error!("surface_redraw_needed"); let key = this.key(env); with_win(key, |win| { win.delegate()?.req_draw(win.win_ref(), win.frame_nano()); use types::WinRef as _; win.win_ref().fresh("surface_redraw_needed"); Some(()) }); } extern "C" fn configuration_changed(_: &JEnv, _: &Self, _: &android::content::res::Configuration) { // DO what? } extern "C" fn on_touch(env: &JEnv, this: &Self, evt: &android::view::MotionEvent) -> JBool { let key = this.key(env); if Some(true) == with_win(key, |win| { use android::view::MotionEvent; match evt.get_action(env)? { MotionEvent::ACTION_DOWN | MotionEvent::ACTION_UP | MotionEvent::ACTION_MOVE | MotionEvent::ACTION_CANCEL => { win.delegate()?.on_touch(win.win_ref(), WinTouch(0, evt, env)); //TODO true } _ => false, } .into() }) { JTRUE } else { JFALSE } } extern "C" fn on_key(env: &JEnv, this: &Self, evt: &android::view::KeyEvent) -> JBool { let key = this.key(env); if with_win(key, |win| { use android::view::KeyEvent; match evt.get_action(env)? { KeyEvent::ACTION_DOWN | KeyEvent::ACTION_UP => { win.delegate()?.on_key(win.win_ref(), WinKey(evt, env)); true } _ => false, } .into() }) == Some(true) { JTRUE } else { JFALSE } } extern "C" fn on_commit_end(env: &JEnv, this: &Self, data: &JString) { let key = this.key(env); with_win(key, |win| { let s = data.try_into_string(env)?; let evt = types::EvtCommit::new(types::Action::End, Some(s.into())); win.delegate()?.on_commit(win.win_ref(), &evt); Some(()) }); } extern "C" fn on_commit_back(env: &JEnv, this: &Self) { let key = this.key(env); with_win(key, |win| { let evt = types::EvtCommit::new(types::Action::Back, None); win.delegate()?.on_commit(win.win_ref(), &evt); Some(()) }); } }