forked from joejulian/gio
app: add RegisterFragment method on *Window for Android
RegisterFragment creates an instance of a Java class and registers it as a Fragment in the window's Context. Signed-off-by: Greg Pomerantz <gmp.gio@wow.st>
This commit is contained in:
committed by
Elias Naur
parent
ce76c2e996
commit
2ca2e5462f
@@ -9,13 +9,6 @@ import (
|
||||
"gioui.org/app/internal/window"
|
||||
)
|
||||
|
||||
type Handle window.Handle
|
||||
|
||||
// PlatformHandle returns the platform specific Handle.
|
||||
func PlatformHandle() *Handle {
|
||||
return (*Handle)(window.PlatformHandle)
|
||||
}
|
||||
|
||||
// extraArgs contains extra arguments to append to
|
||||
// os.Args. The arguments are separated with |.
|
||||
// Useful for running programs on mobiles where the
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"gioui.org/app/internal/window"
|
||||
)
|
||||
|
||||
type Handle window.Handle
|
||||
|
||||
// PlatformHandle returns the Android platform-specific Handle.
|
||||
func PlatformHandle() *Handle {
|
||||
return (*Handle)(window.PlatformHandle)
|
||||
}
|
||||
|
||||
// androidDriver is an interface that allows the Window's run method
|
||||
// to call the RegisterFragment method of the Android window driver.
|
||||
type androidDriver interface {
|
||||
RegisterFragment(string)
|
||||
}
|
||||
|
||||
// RegisterFragment constructs a Java instance of the specified class
|
||||
// and registers it as a Fragment in the Context in which the View was
|
||||
// created.
|
||||
func (w *Window) RegisterFragment(del string) {
|
||||
go func() {
|
||||
w.driverFuncs <- func() {
|
||||
d := w.driver.(androidDriver)
|
||||
d.RegisterFragment(del)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -2,12 +2,21 @@
|
||||
|
||||
package org.gioui;
|
||||
|
||||
import java.lang.Class;
|
||||
import java.lang.IllegalAccessException;
|
||||
import java.lang.InstantiationException;
|
||||
import java.lang.ExceptionInInitializerError;
|
||||
import java.lang.SecurityException;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
import android.text.Editable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Choreographer;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
@@ -57,11 +66,12 @@ public class GioView extends SurfaceView implements Choreographer.FrameCallback
|
||||
|
||||
public GioView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
handler = new Handler();
|
||||
// Late initialization of the Go runtime to wait for a valid context.
|
||||
initialize(context.getApplicationContext());
|
||||
|
||||
nhandle = onCreateView(this);
|
||||
handler = new Handler();
|
||||
imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
@@ -207,6 +217,35 @@ public class GioView extends SurfaceView implements Choreographer.FrameCallback
|
||||
return onBack(nhandle);
|
||||
}
|
||||
|
||||
public void registerFragment(String del) {
|
||||
final Class cls;
|
||||
try {
|
||||
cls = getContext().getClassLoader().loadClass(del);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("RegisterFragment: fragment class not found: " + e.getMessage());
|
||||
}
|
||||
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
final Fragment frag;
|
||||
try {
|
||||
frag = (Fragment)cls.newInstance();
|
||||
} catch (IllegalAccessException | InstantiationException | ExceptionInInitializerError | SecurityException | ClassCastException e) {
|
||||
throw new RuntimeException("RegisterFragment: error instantiating fragment: " + e.getMessage());
|
||||
}
|
||||
final FragmentManager fm;
|
||||
try {
|
||||
fm = ((Activity)getContext()).getFragmentManager();
|
||||
} catch (ClassCastException e) {
|
||||
throw new RuntimeException("RegisterFragment: cannot get fragment manager from View Context: " + e.getMessage());
|
||||
}
|
||||
FragmentTransaction ft = fm.beginTransaction();
|
||||
ft.add(frag, del);
|
||||
ft.commitNow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static private native long onCreateView(GioView view);
|
||||
static private native void onDestroyView(long handle);
|
||||
static private native void onStartView(long handle);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
// +build !android
|
||||
|
||||
package window
|
||||
|
||||
var PlatformHandle *Handle
|
||||
|
||||
type Handle struct{}
|
||||
@@ -166,3 +166,8 @@ void gio_jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *bytes)
|
||||
jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr) {
|
||||
return (*env)->GetArrayLength(env, arr);
|
||||
}
|
||||
|
||||
void gio_jni_RegisterFragment(JNIEnv *env, jobject view, jmethodID mid, char* del) {
|
||||
jstring jdel = (*env)->NewStringUTF(env, del);
|
||||
(*env)->CallObjectMethod(env, view, mid, jdel);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ type window struct {
|
||||
mhideTextInput C.jmethodID
|
||||
mpostFrameCallback C.jmethodID
|
||||
mpostFrameCallbackOnMainThread C.jmethodID
|
||||
mRegisterFragment C.jmethodID
|
||||
}
|
||||
|
||||
var dataDirChan = make(chan string, 1)
|
||||
@@ -119,6 +120,7 @@ func onCreateView(env *C.JNIEnv, class C.jclass, view C.jobject) C.jlong {
|
||||
mhideTextInput: jniGetMethodID(env, class, "hideTextInput", "()V"),
|
||||
mpostFrameCallback: jniGetMethodID(env, class, "postFrameCallback", "()V"),
|
||||
mpostFrameCallbackOnMainThread: jniGetMethodID(env, class, "postFrameCallbackOnMainThread", "()V"),
|
||||
mRegisterFragment: jniGetMethodID(env, class, "registerFragment", "(Ljava/lang/String;)V"),
|
||||
}
|
||||
wopts := <-mainWindow.out
|
||||
w.callbacks = wopts.window
|
||||
@@ -443,6 +445,14 @@ func (w *window) ShowTextInput(show bool) {
|
||||
})
|
||||
}
|
||||
|
||||
func (w *window) RegisterFragment(del string) {
|
||||
runInJVM(func(env *C.JNIEnv) {
|
||||
cdel := C.CString(del)
|
||||
defer C.free(unsafe.Pointer(cdel))
|
||||
C.gio_jni_RegisterFragment(env, w.view, w.mRegisterFragment, cdel)
|
||||
})
|
||||
}
|
||||
|
||||
func Main() {
|
||||
}
|
||||
|
||||
|
||||
@@ -17,3 +17,4 @@ __attribute__ ((visibility ("hidden"))) void gio_jni_CallVoidMethod_J(JNIEnv *en
|
||||
__attribute__ ((visibility ("hidden"))) jbyte *gio_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr);
|
||||
__attribute__ ((visibility ("hidden"))) void gio_jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *bytes);
|
||||
__attribute__ ((visibility ("hidden"))) jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr);
|
||||
__attribute__ ((visibility ("hidden"))) void gio_jni_RegisterFragment(JNIEnv *env, jobject view, jmethodID mid, char* del);
|
||||
|
||||
@@ -29,6 +29,10 @@ type Window struct {
|
||||
driver window.Driver
|
||||
gpu *gpu.GPU
|
||||
|
||||
// driverFuncs is a channel of functions to run when
|
||||
// the Window has a valid driver.
|
||||
driverFuncs chan func()
|
||||
|
||||
out chan event.Event
|
||||
in chan event.Event
|
||||
ack chan struct{}
|
||||
@@ -95,6 +99,7 @@ func NewWindow(options ...Option) *Window {
|
||||
invalidates: make(chan struct{}, 1),
|
||||
frames: make(chan *op.Ops),
|
||||
frameAck: make(chan struct{}),
|
||||
driverFuncs: make(chan func()),
|
||||
}
|
||||
w.callbacks.w = w
|
||||
go w.run(opts)
|
||||
@@ -227,6 +232,10 @@ func (w *Window) run(opts *window.Options) {
|
||||
return
|
||||
}
|
||||
for {
|
||||
var driverFuncs chan func() = nil
|
||||
if w.driver != nil {
|
||||
driverFuncs = w.driverFuncs
|
||||
}
|
||||
var timer <-chan time.Time
|
||||
if w.delayedDraw != nil {
|
||||
timer = w.delayedDraw.C
|
||||
@@ -238,6 +247,8 @@ func (w *Window) run(opts *window.Options) {
|
||||
case <-w.invalidates:
|
||||
w.setNextFrame(time.Time{})
|
||||
w.updateAnimation()
|
||||
case f := <-driverFuncs:
|
||||
f()
|
||||
case e := <-w.in:
|
||||
switch e2 := e.(type) {
|
||||
case system.StageEvent:
|
||||
|
||||
Reference in New Issue
Block a user