Android support refactoring; #119

This commit is contained in:
Vadim Lopatin 2016-04-20 15:21:28 +03:00
parent aed940b2f4
commit 2325d3e4df
4 changed files with 169 additions and 80 deletions

View File

@ -6,6 +6,7 @@ LOCAL_MODULE=dlangui-activity
# applicatino source files # applicatino source files
LOCAL_SRC_FILES="\ LOCAL_SRC_FILES="\
jni/main.d \ jni/main.d \
jni/app.d \
" "
# Additional libraries to link # Additional libraries to link

View File

@ -0,0 +1,77 @@
module app;
import dlangui;
mixin APP_ENTRY_POINT;
/// entry point for dlangui based application
extern (C) int UIAppMain(string[] args) {
// create window
Log.d("Creating window");
if (!Platform.instance) {
Log.e("Platform.instance is null!!!");
}
Window window = Platform.instance.createWindow("DlangUI example - HelloWorld", null);
Log.d("Window created");
// create some widget to show in window
//window.mainWidget = (new Button()).text("Hello, world!"d).margins(Rect(20,20,20,20));
window.mainWidget = parseML(q{
VerticalLayout {
margins: 10
padding: 10
layoutWidth: fill
backgroundColor: "#C0E0E070" // semitransparent yellow background
// red bold text with size = 150% of base style size and font face Arial
TextWidget { text: "Hello World example for DlangUI"; textColor: "red"; fontSize: 150%; fontWeight: 800; fontFace: "Arial" }
// arrange controls as form - table with two columns
TableLayout {
colCount: 2
layoutWidth: fill
TextWidget { text: "param 1" }
EditLine { id: edit1; text: "some text"; layoutWidth: fill }
TextWidget { text: "param 2" }
EditLine { id: edit2; text: "some text for param2"; layoutWidth: fill }
TextWidget { text: "some radio buttons" }
// arrange some radio buttons vertically
VerticalLayout {
layoutWidth: fill
RadioButton { id: rb1; text: "Item 1" }
RadioButton { id: rb2; text: "Item 2" }
RadioButton { id: rb3; text: "Item 3" }
}
TextWidget { text: "and checkboxes" }
// arrange some checkboxes horizontally
HorizontalLayout {
layoutWidth: fill
CheckBox { id: cb1; text: "checkbox 1" }
CheckBox { id: cb2; text: "checkbox 2" }
}
}
HorizontalLayout {
Button { id: btnOk; text: "Ok" }
Button { id: btnCancel; text: "Cancel" }
}
}
});
// you can access loaded items by id - e.g. to assign signal listeners
auto edit1 = window.mainWidget.childById!EditLine("edit1");
auto edit2 = window.mainWidget.childById!EditLine("edit2");
// close window on Cancel button click
window.mainWidget.childById!Button("btnCancel").click = delegate(Widget w) {
window.close();
return true;
};
// show message box with content of editors
window.mainWidget.childById!Button("btnOk").click = delegate(Widget w) {
window.showMessageBox(UIString("Ok button pressed"d),
UIString("Editors content\nEdit1: "d ~ edit1.text ~ "\nEdit2: "d ~ edit2.text));
return true;
};
// show window
window.show();
// run message loop
return Platform.instance.enterMessageLoop();
}

View File

@ -92,10 +92,34 @@ class AndroidPlatform : Platform {
protected AndroidWindow[] _windows; protected AndroidWindow[] _windows;
protected AndroidWindow _activeWindow; protected AndroidWindow _activeWindow;
engine _engine;
protected android_app* _appstate; protected android_app* _appstate;
this(android_app* state) { this(android_app* state) {
_appstate = state; _appstate = state;
memset(&_engine, 0, engine.sizeof);
state.userData = &_engine;
state.onAppCmd = &engine_handle_cmd;
state.onInputEvent = &engine_handle_input;
_engine.app = state;
// Prepare to monitor accelerometer
_engine.sensorManager = ASensorManager_getInstance();
_engine.accelerometerSensor = ASensorManager_getDefaultSensor(_engine.sensorManager,
ASENSOR_TYPE_ACCELEROMETER);
_engine.sensorEventQueue = ASensorManager_createEventQueue(_engine.sensorManager,
state.looper, LOOPER_ID_USER, null, null);
if (state.savedState != null) {
// We are starting with a previous saved state; restore from it.
_engine.state = *cast(saved_state*)state.savedState;
}
}
~this() {
engine_term_display(&_engine);
} }
/** /**
@ -138,9 +162,55 @@ class AndroidPlatform : Platform {
* When returned from this method, application is shutting down. * When returned from this method, application is shutting down.
*/ */
override int enterMessageLoop() { override int enterMessageLoop() {
// TODO: while (1) {
// Read all pending events.
int ident;
int events;
android_poll_source* source;
// If not animating, we will block forever waiting for events.
// If animating, we loop until all events are read, then continue
// to draw the next frame of animation.
while ((ident=ALooper_pollAll(_engine.animating ? 0 : -1, null, &events,
cast(void**)&source)) >= 0) {
// Process this event.
if (source != null) {
source.process(_appstate, source);
}
// If a sensor has data, process it now.
if (ident == LOOPER_ID_USER) {
if (_engine.accelerometerSensor != null) {
ASensorEvent event;
while (ASensorEventQueue_getEvents(_engine.sensorEventQueue,
&event, 1) > 0) {
LOGI("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y,
event.acceleration.z);
}
}
}
// Check if we are exiting.
if (_appstate.destroyRequested != 0) {
return 0; return 0;
} }
}
if (_engine.animating) {
// Done with events; draw next animation frame.
_engine.state.angle += .01f;
if (_engine.state.angle > 1) {
_engine.state.angle = 0;
}
// Drawing is throttled to the screen update rate, so there
// is no need to do timing here.
engine_draw_frame(&_engine);
}
}
}
protected dstring _clipboardText; protected dstring _clipboardText;
/// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) /// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
@ -393,63 +463,17 @@ extern (C) void android_main(android_app* state) {
Platform.setInstance(_platform); Platform.setInstance(_platform);
engine engine;
// Make sure glue isn't stripped. // Make sure glue isn't stripped.
app_dummy(); app_dummy();
memset(&engine, 0, engine.sizeof); int res = 0;
state.userData = &engine;
state.onAppCmd = &engine_handle_cmd;
state.onInputEvent = &engine_handle_input;
engine.app = state;
// Prepare to monitor accelerometer version (unittest) {
engine.sensorManager = ASensorManager_getInstance(); } else {
engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, res = UIAppMain([]);
ASENSOR_TYPE_ACCELEROMETER);
engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
state.looper, LOOPER_ID_USER, null, null);
if (state.savedState != null) {
// We are starting with a previous saved state; restore from it.
engine.state = *cast(saved_state*)state.savedState;
} }
// loop waiting for stuff to do. // loop waiting for stuff to do.
while (1) {
// Read all pending events.
int ident;
int events;
android_poll_source* source;
// If not animating, we will block forever waiting for events.
// If animating, we loop until all events are read, then continue
// to draw the next frame of animation.
while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, null, &events,
cast(void**)&source)) >= 0) {
// Process this event.
if (source != null) {
source.process(state, source);
}
// If a sensor has data, process it now.
if (ident == LOOPER_ID_USER) {
if (engine.accelerometerSensor != null) {
ASensorEvent event;
while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
&event, 1) > 0) {
LOGI("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y,
event.acceleration.z);
}
}
}
// Check if we are exiting.
if (state.destroyRequested != 0) {
Log.d("Destroying Android platform"); Log.d("Destroying Android platform");
Platform.setInstance(null); Platform.setInstance(null);
@ -457,22 +481,6 @@ extern (C) void android_main(android_app* state) {
Log.d("Exiting main"); Log.d("Exiting main");
engine_term_display(&engine);
return;
}
}
if (engine.animating) {
// Done with events; draw next animation frame.
engine.state.angle += .01f;
if (engine.state.angle > 1) {
engine.state.angle = 0;
}
// Drawing is throttled to the screen update rate, so there
// is no need to do timing here.
engine_draw_frame(&engine);
}
}
} }

View File

@ -1439,6 +1439,8 @@ mixin template APP_ENTRY_POINT() {
return 1; return 1;
} }
} }
} else {
version (Android) {
} else { } else {
int main(string[] args) int main(string[] args)
{ {
@ -1446,6 +1448,7 @@ mixin template APP_ENTRY_POINT() {
} }
} }
} }
}
/// initialize font manager on startup /// initialize font manager on startup
extern(C) bool initFontManager(); extern(C) bool initFontManager();