mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 04:41:05 +08:00
Merge branch 'android_improvements'
This commit is contained in:
commit
3f69629d0c
@ -42,6 +42,7 @@
|
||||
#include <SFML/System/Sleep.hpp>
|
||||
#include <SFML/System/Thread.hpp>
|
||||
#include <SFML/System/Lock.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <android/window.h>
|
||||
#include <android/native_activity.h>
|
||||
|
||||
@ -94,12 +95,6 @@ void* main(ActivityStates* states)
|
||||
// Initialize the thread before giving the hand
|
||||
initializeMain(states);
|
||||
|
||||
{
|
||||
Lock lock(states->mutex);
|
||||
|
||||
states->initialized = true;
|
||||
}
|
||||
|
||||
sleep(seconds(0.5));
|
||||
::main(0, NULL);
|
||||
|
||||
@ -119,6 +114,80 @@ void* main(ActivityStates* states)
|
||||
} // namespace sf
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void goToFullscreenMode(ANativeActivity* activity)
|
||||
{
|
||||
// Hide the status bar
|
||||
ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_FULLSCREEN,
|
||||
AWINDOW_FLAG_FULLSCREEN);
|
||||
|
||||
// Hide the navigation bar
|
||||
JavaVM* lJavaVM = activity->vm;
|
||||
JNIEnv* lJNIEnv = activity->env;
|
||||
|
||||
jobject objectActivity = activity->clazz;
|
||||
jclass classActivity = lJNIEnv->GetObjectClass(objectActivity);
|
||||
|
||||
jmethodID methodGetWindow = lJNIEnv->GetMethodID(classActivity, "getWindow", "()Landroid/view/Window;");
|
||||
jobject objectWindow = lJNIEnv->CallObjectMethod(objectActivity, methodGetWindow);
|
||||
|
||||
jclass classWindow = lJNIEnv->FindClass("android/view/Window");
|
||||
jmethodID methodGetDecorView = lJNIEnv->GetMethodID(classWindow, "getDecorView", "()Landroid/view/View;");
|
||||
jobject objectDecorView = lJNIEnv->CallObjectMethod(objectWindow, methodGetDecorView);
|
||||
|
||||
jclass classView = lJNIEnv->FindClass("android/view/View");
|
||||
|
||||
jfieldID FieldSYSTEM_UI_FLAG_LOW_PROFILE = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_LOW_PROFILE", "I");
|
||||
jint SYSTEM_UI_FLAG_LOW_PROFILE = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_LOW_PROFILE);
|
||||
|
||||
jfieldID FieldSYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_FULLSCREEN", "I");
|
||||
jint SYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_FULLSCREEN);
|
||||
|
||||
//jfieldID FieldSYSTEM_UI_FLAG_IMMERSIVE_STICKY = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_IMMERSIVE_STICKY", "I");
|
||||
//jint SYSTEM_UI_FLAG_IMMERSIVE_STICKY = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||
|
||||
jmethodID methodsetSystemUiVisibility = lJNIEnv->GetMethodID(classView, "setSystemUiVisibility", "(I)V");
|
||||
lJNIEnv->CallVoidMethod(objectDecorView, methodsetSystemUiVisibility, SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN | 0x00001000);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
void getScreenSizeInPixels(ANativeActivity* activity, int* width, int* height)
|
||||
{
|
||||
// Perform the following java code:
|
||||
//
|
||||
// DisplayMetrics dm = new DisplayMetrics();
|
||||
// getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
|
||||
JavaVM* lJavaVM = activity->vm;
|
||||
JNIEnv* lJNIEnv = activity->env;
|
||||
|
||||
jobject objectActivity = activity->clazz;
|
||||
jclass classActivity = lJNIEnv->GetObjectClass(objectActivity);
|
||||
|
||||
jclass classDisplayMetrics = lJNIEnv->FindClass("android/util/DisplayMetrics");
|
||||
jmethodID initDisplayMetrics = lJNIEnv->GetMethodID(classDisplayMetrics, "<init>", "()V");
|
||||
jobject objectDisplayMetrics = lJNIEnv->NewObject(classDisplayMetrics, initDisplayMetrics);
|
||||
|
||||
jmethodID methodGetWindowManager = lJNIEnv->GetMethodID(classActivity, "getWindowManager", "()Landroid/view/WindowManager;");
|
||||
jobject objectWindowManager = lJNIEnv->CallObjectMethod(objectActivity, methodGetWindowManager);
|
||||
|
||||
jclass classWindowManager = lJNIEnv->FindClass("android/view/WindowManager");
|
||||
jmethodID methodGetDefaultDisplay = lJNIEnv->GetMethodID(classWindowManager, "getDefaultDisplay", "()Landroid/view/Display;");
|
||||
jobject objectDisplay = lJNIEnv->CallObjectMethod(objectWindowManager, methodGetDefaultDisplay);
|
||||
|
||||
jclass classDisplay = lJNIEnv->FindClass("android/view/Display");
|
||||
jmethodID methodGetMetrics = lJNIEnv->GetMethodID(classDisplay, "getMetrics", "(Landroid/util/DisplayMetrics;)V");
|
||||
lJNIEnv->CallVoidMethod(objectDisplay, methodGetMetrics, objectDisplayMetrics);
|
||||
|
||||
jfieldID fieldWidthPixels = lJNIEnv->GetFieldID(classDisplayMetrics, "widthPixels", "I");
|
||||
jfieldID fieldHeightPixels = lJNIEnv->GetFieldID(classDisplayMetrics, "heightPixels", "I");
|
||||
|
||||
*width = lJNIEnv->GetIntField(objectDisplayMetrics, fieldWidthPixels);
|
||||
*height = lJNIEnv->GetIntField(objectDisplayMetrics, fieldHeightPixels);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
static void onStart(ANativeActivity* activity)
|
||||
{
|
||||
@ -132,11 +201,14 @@ static void onResume(ANativeActivity* activity)
|
||||
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
|
||||
sf::Lock lock(states->mutex);
|
||||
|
||||
if (states->fullscreen)
|
||||
goToFullscreenMode(activity);
|
||||
|
||||
// Send an event to warn people the activity has been resumed
|
||||
sf::Event event;
|
||||
event.type = sf::Event::MouseEntered;
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
states->forwardEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@ -151,7 +223,7 @@ static void onPause(ANativeActivity* activity)
|
||||
sf::Event event;
|
||||
event.type = sf::Event::MouseLeft;
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
states->forwardEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@ -178,7 +250,7 @@ static void onDestroy(ANativeActivity* activity)
|
||||
sf::Event event;
|
||||
event.type = sf::Event::Closed;
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
states->forwardEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +291,7 @@ static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* wind
|
||||
// Notify SFML mechanism
|
||||
sf::Event event;
|
||||
event.type = sf::Event::GainedFocus;
|
||||
states->pendingEvents.push_back(event);
|
||||
states->forwardEvent(event);
|
||||
|
||||
// Wait for the event to be taken into account by SFML
|
||||
states->updated = false;
|
||||
@ -244,7 +316,7 @@ static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* wi
|
||||
// Notify SFML mechanism
|
||||
sf::Event event;
|
||||
event.type = sf::Event::LostFocus;
|
||||
states->pendingEvents.push_back(event);
|
||||
states->forwardEvent(event);
|
||||
|
||||
// Wait for the event to be taken into account by SFML
|
||||
states->updated = false;
|
||||
@ -320,7 +392,7 @@ static void onContentRectChanged(ANativeActivity* activity, const ARect* rect)
|
||||
event.size.width = ANativeWindow_getWidth(states->window);
|
||||
event.size.height = ANativeWindow_getHeight(states->window);
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
states->forwardEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@ -345,14 +417,6 @@ static void onLowMemory(ANativeActivity* activity)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
int dummyProcessEvent(int fd, int events, void* data)
|
||||
{
|
||||
// Do nothing
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize)
|
||||
{
|
||||
@ -370,14 +434,10 @@ void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_
|
||||
for (unsigned int i = 0; i < sf::Mouse::ButtonCount; i++)
|
||||
states->isButtonPressed[i] = false;
|
||||
|
||||
states->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
states->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
|
||||
// As the input queue will be created before the SFML window, we need to use
|
||||
// this dummy function that will be replaced later by the first created
|
||||
// SFML window
|
||||
states->processEvent = dummyProcessEvent;
|
||||
|
||||
if (savedState != NULL) {
|
||||
if (savedState != NULL)
|
||||
{
|
||||
states->savedState = malloc(savedStateSize);
|
||||
states->savedStateSize = savedStateSize;
|
||||
memcpy(states->savedState, savedState, savedStateSize);
|
||||
@ -421,38 +481,14 @@ void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_
|
||||
ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_KEEP_SCREEN_ON,
|
||||
AWINDOW_FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
// Hide the status bar
|
||||
ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_FULLSCREEN,
|
||||
AWINDOW_FLAG_FULLSCREEN);
|
||||
|
||||
// Hide the navigation bar
|
||||
JavaVM* lJavaVM = activity->vm;
|
||||
JNIEnv* lJNIEnv = activity->env;
|
||||
|
||||
jobject objectActivity = activity->clazz;
|
||||
jclass classActivity = lJNIEnv->GetObjectClass(objectActivity);
|
||||
|
||||
jmethodID methodGetWindow = lJNIEnv->GetMethodID(classActivity, "getWindow", "()Landroid/view/Window;");
|
||||
jobject objectWindow = lJNIEnv->CallObjectMethod(objectActivity, methodGetWindow);
|
||||
|
||||
jclass classWindow = lJNIEnv->FindClass("android/view/Window");
|
||||
jmethodID methodGetDecorView = lJNIEnv->GetMethodID(classWindow, "getDecorView", "()Landroid/view/View;");
|
||||
jobject objectDecorView = lJNIEnv->CallObjectMethod(objectWindow, methodGetDecorView);
|
||||
|
||||
jclass classView = lJNIEnv->FindClass("android/view/View");
|
||||
|
||||
jfieldID FieldSYSTEM_UI_FLAG_HIDE_NAVIGATION = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_HIDE_NAVIGATION", "I");
|
||||
jint SYSTEM_UI_FLAG_HIDE_NAVIGATION = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
|
||||
jfieldID FieldSYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_FULLSCREEN", "I");
|
||||
jint SYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_FULLSCREEN);
|
||||
|
||||
jmethodID methodsetSystemUiVisibility = lJNIEnv->GetMethodID(classView, "setSystemUiVisibility", "(I)V");
|
||||
lJNIEnv->CallVoidMethod(objectDecorView, methodsetSystemUiVisibility, SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
|
||||
// Initialize the display
|
||||
eglInitialize(states->display, NULL, NULL);
|
||||
|
||||
getScreenSizeInPixels(activity, &states->screenSize.x, &states->screenSize.y);
|
||||
|
||||
// Redirect error messages to logcat
|
||||
sf::err().rdbuf(&states->logcat);
|
||||
|
||||
// Launch the main thread
|
||||
sf::Thread* thread = new sf::Thread(sf::priv::main, states);
|
||||
thread->launch();
|
||||
|
@ -28,6 +28,29 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Android/Activity.hpp>
|
||||
#include <android/log.h>
|
||||
|
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_INFO, "sfml-error", __VA_ARGS__))
|
||||
|
||||
LogcatStream::LogcatStream() :
|
||||
std::streambuf()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
std::streambuf::int_type LogcatStream::overflow (std::streambuf::int_type c)
|
||||
{
|
||||
if (c == "\n"[0])
|
||||
{
|
||||
m_message.push_back(c);
|
||||
LOGE(m_message.c_str());
|
||||
m_message.clear();
|
||||
}
|
||||
|
||||
m_message.push_back(c);
|
||||
|
||||
return traits_type::not_eof(c);
|
||||
}
|
||||
|
||||
namespace sf
|
||||
{
|
||||
|
@ -36,7 +36,19 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
class SFML_SYSTEM_API LogcatStream : public std::streambuf
|
||||
{
|
||||
public:
|
||||
LogcatStream();
|
||||
|
||||
std::streambuf::int_type overflow (std::streambuf::int_type c);
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
|
||||
namespace sf
|
||||
{
|
||||
@ -59,7 +71,7 @@ struct ActivityStates
|
||||
|
||||
Mutex mutex;
|
||||
|
||||
std::vector<Event> pendingEvents;
|
||||
void (*forwardEvent)(const Event& event);
|
||||
int (*processEvent)(int fd, int events, void* data);
|
||||
|
||||
std::map<int, Vector2i> touchEvents;
|
||||
@ -68,10 +80,16 @@ struct ActivityStates
|
||||
|
||||
bool mainOver;
|
||||
|
||||
Vector2i screenSize;
|
||||
|
||||
bool initialized;
|
||||
bool terminated;
|
||||
|
||||
bool fullscreen;
|
||||
|
||||
bool updated;
|
||||
|
||||
LogcatStream logcat;
|
||||
};
|
||||
|
||||
SFML_SYSTEM_API ActivityStates* getActivity(ActivityStates* initializedStates=NULL, bool reset=false);
|
||||
|
@ -90,7 +90,7 @@ if(SFML_OS_WINDOWS)
|
||||
list(APPEND SYSTEM_EXT_LIBS winmm)
|
||||
endif()
|
||||
if(SFML_OS_ANDROID)
|
||||
list(APPEND SYSTEM_EXT_LIBS android)
|
||||
list(APPEND SYSTEM_EXT_LIBS android log)
|
||||
endif()
|
||||
|
||||
# define the sfml-system target
|
||||
|
@ -55,20 +55,7 @@ VideoMode VideoModeImpl::getDesktopMode()
|
||||
priv::ActivityStates* states = priv::getActivity(NULL);
|
||||
Lock lock(states->mutex);
|
||||
|
||||
// Wait for a window if there's none
|
||||
while (!states->window)
|
||||
{
|
||||
states->mutex.unlock();
|
||||
sleep(milliseconds(10));
|
||||
states->mutex.lock();
|
||||
}
|
||||
|
||||
// Get size from the window
|
||||
Vector2i size;
|
||||
size.x = ANativeWindow_getWidth(states->window);
|
||||
size.y = ANativeWindow_getHeight(states->window);
|
||||
|
||||
return VideoMode(size.x, size.y);
|
||||
return VideoMode(states->screenSize.x, states->screenSize.y);
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
@ -44,24 +44,36 @@ namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
WindowImplAndroid* WindowImplAndroid::singleInstance = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplAndroid::WindowImplAndroid(WindowHandle handle)
|
||||
: m_size(0, 0)
|
||||
, m_windowBeingCreated(false)
|
||||
, m_windowBeingDestroyed(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplAndroid::WindowImplAndroid(VideoMode mode, const String& title, unsigned long style, const ContextSettings& settings)
|
||||
: m_size(mode.width, mode.height)
|
||||
, m_windowBeingCreated(false)
|
||||
, m_windowBeingDestroyed(false)
|
||||
{
|
||||
ActivityStates* states = getActivity(NULL);
|
||||
Lock lock(states->mutex);
|
||||
|
||||
// Replace our dummy process event function with the actual one
|
||||
AInputQueue_detachLooper(states->inputQueue);
|
||||
AInputQueue_attachLooper(states->inputQueue, states->looper, 1, processEvent, NULL);
|
||||
if (style& Style::Fullscreen)
|
||||
states->fullscreen = true;
|
||||
|
||||
// Register the actual process event function so it can be set automatically later by the OS
|
||||
WindowImplAndroid::singleInstance = this;
|
||||
states->forwardEvent = forwardEvent;
|
||||
|
||||
// Register process event callback
|
||||
states->processEvent = processEvent;
|
||||
|
||||
states->initialized = true;
|
||||
}
|
||||
|
||||
|
||||
@ -84,30 +96,25 @@ WindowHandle WindowImplAndroid::getSystemHandle() const
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplAndroid::processEvents()
|
||||
{
|
||||
ActivityStates* states = getActivity(NULL);
|
||||
Lock lock(states->mutex);
|
||||
|
||||
// Process incoming OS events
|
||||
ALooper_pollAll(0, NULL, NULL, NULL);
|
||||
|
||||
while (!states->pendingEvents.empty())
|
||||
ActivityStates* states = getActivity(NULL);
|
||||
sf::Lock lock(states->mutex);
|
||||
|
||||
if (m_windowBeingCreated)
|
||||
{
|
||||
Event tempEvent = states->pendingEvents.back();
|
||||
states->pendingEvents.pop_back();
|
||||
|
||||
if (tempEvent.type == Event::GainedFocus)
|
||||
{
|
||||
states->context->createSurface(states->window);
|
||||
states->updated = true;
|
||||
}
|
||||
else if (tempEvent.type == Event::LostFocus)
|
||||
{
|
||||
states->context->destroySurface();
|
||||
states->updated = true;
|
||||
}
|
||||
|
||||
pushEvent(tempEvent);
|
||||
states->context->createSurface(states->window);
|
||||
m_windowBeingCreated = false;
|
||||
}
|
||||
|
||||
if (m_windowBeingDestroyed)
|
||||
{
|
||||
states->context->destroySurface();
|
||||
m_windowBeingDestroyed = false;
|
||||
}
|
||||
|
||||
states->updated = true;
|
||||
}
|
||||
|
||||
|
||||
@ -129,13 +136,7 @@ void WindowImplAndroid::setPosition(const Vector2i& position)
|
||||
////////////////////////////////////////////////////////////
|
||||
Vector2u WindowImplAndroid::getSize() const
|
||||
{
|
||||
ActivityStates* states = getActivity(NULL);
|
||||
Lock lock(states->mutex);
|
||||
|
||||
int32_t width = ANativeWindow_getWidth(states->window);
|
||||
int32_t height = ANativeWindow_getHeight(states->window);
|
||||
|
||||
return Vector2u(static_cast<unsigned int>(width), static_cast<unsigned int>(height));
|
||||
return m_size;
|
||||
}
|
||||
|
||||
|
||||
@ -180,6 +181,26 @@ void WindowImplAndroid::setKeyRepeatEnabled(bool enabled)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplAndroid::forwardEvent(const Event& event)
|
||||
{
|
||||
ActivityStates* states = getActivity(NULL);
|
||||
|
||||
if (event.type == Event::GainedFocus)
|
||||
{
|
||||
WindowImplAndroid::singleInstance->m_size.x = ANativeWindow_getWidth(states->window);
|
||||
WindowImplAndroid::singleInstance->m_size.y = ANativeWindow_getHeight(states->window);
|
||||
WindowImplAndroid::singleInstance->m_windowBeingCreated = true;
|
||||
}
|
||||
else if (event.type == Event::LostFocus)
|
||||
{
|
||||
WindowImplAndroid::singleInstance->m_windowBeingDestroyed = true;
|
||||
}
|
||||
|
||||
WindowImplAndroid::singleInstance->pushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
int WindowImplAndroid::processEvent(int fd, int events, void* data)
|
||||
{
|
||||
@ -192,7 +213,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
|
||||
{
|
||||
if (AInputQueue_preDispatchEvent(states->inputQueue, _event))
|
||||
return 1;
|
||||
|
||||
|
||||
int32_t handled = 0;
|
||||
|
||||
int32_t type = AInputEvent_getType(_event);
|
||||
@ -209,7 +230,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
|
||||
else if (type == AINPUT_EVENT_TYPE_MOTION)
|
||||
{
|
||||
int32_t action = AMotionEvent_getAction(_event);
|
||||
|
||||
|
||||
switch (action & AMOTION_EVENT_ACTION_MASK)
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_SCROLL:
|
||||
@ -217,7 +238,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
|
||||
processScrollEvent(_event, states);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case AMOTION_EVENT_ACTION_HOVER_MOVE:
|
||||
case AMOTION_EVENT_ACTION_MOVE:
|
||||
{
|
||||
@ -285,7 +306,7 @@ void WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates*
|
||||
jfloat yPrecision = AMotionEvent_getYPrecision(_event);
|
||||
jint deviceId = AInputEvent_getDeviceId(_event);
|
||||
jint edgeFlags = AMotionEvent_getEdgeFlags(_event);
|
||||
|
||||
|
||||
// Create the MotionEvent object in java trough its static constructor obtain()
|
||||
jclass ClassMotionEvent = lJNIEnv->FindClass("android/view/MotionEvent");
|
||||
jmethodID StaticMethodObtain = lJNIEnv->GetStaticMethodID(ClassMotionEvent, "obtain", "(JJIFFFFIFFII)Landroid/view/MotionEvent;");
|
||||
@ -294,15 +315,15 @@ void WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates*
|
||||
// Call its getAxisValue() method to get the delta value of our wheel move event
|
||||
jmethodID MethodGetAxisValue = lJNIEnv->GetMethodID(ClassMotionEvent, "getAxisValue", "(I)F");
|
||||
jfloat delta = lJNIEnv->CallFloatMethod(ObjectMotionEvent, MethodGetAxisValue, 0x00000001);
|
||||
|
||||
|
||||
// Create and send our mouse wheel event
|
||||
Event event;
|
||||
event.type = Event::MouseWheelMoved;
|
||||
event.mouseWheel.delta = static_cast<double>(delta);
|
||||
event.mouseWheel.x = AMotionEvent_getX(_event, 0);
|
||||
event.mouseWheel.y = AMotionEvent_getY(_event, 0);
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
|
||||
forwardEvent(event);
|
||||
|
||||
// Dettach this thread from the JVM
|
||||
lJavaVM->DetachCurrentThread();
|
||||
@ -314,7 +335,7 @@ void WindowImplAndroid::processKeyEvent(AInputEvent* _event, ActivityStates* sta
|
||||
{
|
||||
int32_t device = AInputEvent_getSource(_event);
|
||||
int32_t action = AKeyEvent_getAction(_event);
|
||||
|
||||
|
||||
int32_t key = AKeyEvent_getKeyCode(_event);
|
||||
int32_t metakey = AKeyEvent_getMetaState(_event);
|
||||
|
||||
@ -325,14 +346,14 @@ void WindowImplAndroid::processKeyEvent(AInputEvent* _event, ActivityStates* sta
|
||||
event.key.control = false;
|
||||
event.key.shift = metakey & AMETA_SHIFT_ON;
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
forwardEvent(event);
|
||||
|
||||
if (int unicode = getUnicode(_event))
|
||||
{
|
||||
Event event;
|
||||
event.type = Event::TextEntered;
|
||||
event.text.unicode = unicode;
|
||||
states->pendingEvents.push_back(event);
|
||||
forwardEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,26 +365,26 @@ void WindowImplAndroid::processMotionEvent(AInputEvent* _event, ActivityStates*
|
||||
int32_t action = AMotionEvent_getAction(_event);
|
||||
|
||||
Event event;
|
||||
|
||||
|
||||
if (device == AINPUT_SOURCE_MOUSE)
|
||||
event.type = Event::MouseMoved;
|
||||
else if (device == AINPUT_SOURCE_TOUCHSCREEN)
|
||||
event.type = Event::TouchMoved;
|
||||
|
||||
int pointerCount = AMotionEvent_getPointerCount(_event);
|
||||
|
||||
|
||||
for (int p = 0; p < pointerCount; p++)
|
||||
{
|
||||
int id = AMotionEvent_getPointerId(_event, p);
|
||||
|
||||
float x = AMotionEvent_getX(_event, p);
|
||||
float y = AMotionEvent_getY(_event, p);
|
||||
|
||||
|
||||
if (device == AINPUT_SOURCE_MOUSE)
|
||||
{
|
||||
event.mouseMove.x = x;
|
||||
event.mouseMove.y = y;
|
||||
|
||||
|
||||
states->mousePosition = Vector2i(event.mouseMove.x, event.mouseMove.y);
|
||||
}
|
||||
else if (device == AINPUT_SOURCE_TOUCHSCREEN)
|
||||
@ -374,11 +395,11 @@ void WindowImplAndroid::processMotionEvent(AInputEvent* _event, ActivityStates*
|
||||
event.touch.finger = id;
|
||||
event.touch.x = x;
|
||||
event.touch.y = y;
|
||||
|
||||
|
||||
states->touchEvents[id] = Vector2i(event.touch.x, event.touch.y);
|
||||
}
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
|
||||
forwardEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,13 +409,13 @@ void WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Ac
|
||||
{
|
||||
int32_t device = AInputEvent_getSource(_event);
|
||||
int32_t action = AMotionEvent_getAction(_event);
|
||||
|
||||
|
||||
int index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||
int id = AMotionEvent_getPointerId(_event, index);
|
||||
|
||||
float x = AMotionEvent_getX(_event, index);
|
||||
float y = AMotionEvent_getY(_event, index);
|
||||
|
||||
|
||||
Event event;
|
||||
|
||||
if (isDown)
|
||||
@ -405,7 +426,7 @@ void WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Ac
|
||||
event.mouseButton.button = static_cast<Mouse::Button>(id);
|
||||
event.mouseButton.x = x;
|
||||
event.mouseButton.y = y;
|
||||
|
||||
|
||||
if (id >= 0 && id < Mouse::ButtonCount)
|
||||
states->isButtonPressed[id] = true;
|
||||
}
|
||||
@ -415,7 +436,7 @@ void WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Ac
|
||||
event.touch.finger = id;
|
||||
event.touch.x = x;
|
||||
event.touch.y = y;
|
||||
|
||||
|
||||
states->touchEvents[id] = Vector2i(event.touch.x, event.touch.y);
|
||||
}
|
||||
}
|
||||
@ -427,7 +448,7 @@ void WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Ac
|
||||
event.mouseButton.button = static_cast<Mouse::Button>(id);
|
||||
event.mouseButton.x = x;
|
||||
event.mouseButton.y = y;
|
||||
|
||||
|
||||
if (id >= 0 && id < Mouse::ButtonCount)
|
||||
states->isButtonPressed[id] = false;
|
||||
}
|
||||
@ -437,12 +458,12 @@ void WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Ac
|
||||
event.touch.finger = id;
|
||||
event.touch.x = x;
|
||||
event.touch.y = y;
|
||||
|
||||
|
||||
states->touchEvents.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
states->pendingEvents.push_back(event);
|
||||
|
||||
forwardEvent(event);
|
||||
}
|
||||
|
||||
|
||||
|
@ -154,6 +154,9 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setKeyRepeatEnabled(bool enabled);
|
||||
|
||||
static void forwardEvent(const Event& event);
|
||||
static WindowImplAndroid* singleInstance;
|
||||
|
||||
protected :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -190,7 +193,7 @@ private:
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key androidKeyToSF(int32_t key);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get unicode decoded from the input event
|
||||
///
|
||||
@ -200,6 +203,10 @@ private:
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static int getUnicode(AInputEvent* event);
|
||||
|
||||
Vector2u m_size;
|
||||
bool m_windowBeingCreated;
|
||||
bool m_windowBeingDestroyed;
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -109,9 +109,16 @@ void Window::create(VideoMode mode, const String& title, Uint32 style, const Con
|
||||
}
|
||||
}
|
||||
|
||||
// Check validity of style
|
||||
if ((style & Style::Close) || (style & Style::Resize))
|
||||
style |= Style::Titlebar;
|
||||
// Check validity of style according to the underlying platform
|
||||
#if defined(SFML_SYSTEM_IOS) || defined(SFML_SYSTEM_ANDROID)
|
||||
if (style & Style::Fullscreen)
|
||||
style &= ~Style::Titlebar;
|
||||
else
|
||||
style |= Style::Titlebar;
|
||||
#else
|
||||
if ((style & Style::Close) || (style & Style::Resize))
|
||||
style |= Style::Titlebar;
|
||||
#endif
|
||||
|
||||
// Recreate the window implementation
|
||||
m_impl = priv::WindowImpl::create(mode, title, style, settings);
|
||||
|
Loading…
Reference in New Issue
Block a user