Merge remote-tracking branch 'upstream/master' into max-json-size
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME native-lib)
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared task networking gl gpu qml image fbx render-utils physics entities octree ${PLATFORM_GL_BACKEND})
|
||||
link_hifi_libraries(shared task networking gl gpu qml image fbx hfm render-utils physics entities octree ${PLATFORM_GL_BACKEND})
|
||||
target_opengl()
|
||||
target_bullet()
|
||||
|
||||
|
|
|
@ -51,6 +51,9 @@ android {
|
|||
debug {
|
||||
buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\""
|
||||
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\""
|
||||
buildConfigField "String", "OAUTH_CLIENT_ID", "\"" + (System.getenv("OAUTH_CLIENT_ID") ? System.getenv("OAUTH_CLIENT_ID") : '') + "\""
|
||||
buildConfigField "String", "OAUTH_CLIENT_SECRET", "\"" + (System.getenv("OAUTH_CLIENT_SECRET") ? System.getenv("OAUTH_CLIENT_SECRET") : '') + "\""
|
||||
buildConfigField "String", "OAUTH_REDIRECT_URI", "\"" + (System.getenv("OAUTH_REDIRECT_URI") ? System.getenv("OAUTH_REDIRECT_URI") : '') + "\""
|
||||
}
|
||||
release {
|
||||
minifyEnabled false
|
||||
|
@ -61,6 +64,9 @@ android {
|
|||
project.hasProperty("HIFI_ANDROID_KEY_PASSWORD")? signingConfigs.release : null
|
||||
buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\""
|
||||
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\""
|
||||
buildConfigField "String", "OAUTH_CLIENT_ID", "\"" + (System.getenv("OAUTH_CLIENT_ID") ? System.getenv("OAUTH_CLIENT_ID") : '') + "\""
|
||||
buildConfigField "String", "OAUTH_CLIENT_SECRET", "\"" + (System.getenv("OAUTH_CLIENT_SECRET") ? System.getenv("OAUTH_CLIENT_SECRET") : '') + "\""
|
||||
buildConfigField "String", "OAUTH_REDIRECT_URI", "\"" + (System.getenv("OAUTH_REDIRECT_URI") ? System.getenv("OAUTH_REDIRECT_URI") : '') + "\""
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,10 @@
|
|||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Translucent.NoActionBar" />
|
||||
|
||||
<activity android:name=".LoginMenuActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Translucent.NoActionBar" />
|
||||
|
||||
<service
|
||||
android:name=".BreakpadUploaderService"
|
||||
android:enabled="true"
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include <udt/PacketHeaders.h>
|
||||
#include <SettingHandle.h>
|
||||
|
||||
#define AUTO_LOGOUT_SETTING_NAME "wallet/autoLogout"
|
||||
#define WALLET_USERNAME_SETTING_NAME "wallet/savedUsername"
|
||||
|
||||
QAndroidJniObject __interfaceActivity;
|
||||
QAndroidJniObject __loginCompletedListener;
|
||||
QAndroidJniObject __signupCompletedListener;
|
||||
|
@ -210,11 +213,13 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnDest
|
|||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeGotoUrl(JNIEnv* env, jobject obj, jstring url) {
|
||||
QAndroidJniObject jniUrl("java/lang/String", "(Ljava/lang/String;)V", url);
|
||||
DependencyManager::get<AddressManager>()->loadSettings(jniUrl.toString());
|
||||
AndroidHelper::instance().muteMic();
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeGoToUser(JNIEnv* env, jobject obj, jstring username) {
|
||||
QAndroidJniObject jniUsername("java/lang/String", "(Ljava/lang/String;)V", username);
|
||||
DependencyManager::get<AddressManager>()->goToUser(jniUsername.toString(), false);
|
||||
AndroidHelper::instance().muteMic();
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnPause(JNIEnv* env, jobject obj) {
|
||||
|
@ -259,7 +264,56 @@ JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_fragment_HomeFragme
|
|||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeCancelLogin(JNIEnv *env, jobject instance) {
|
||||
Java_io_highfidelity_hifiinterface_HifiUtils_updateHifiSetting(JNIEnv *env, jobject instance,
|
||||
jstring group_, jstring key_,
|
||||
jboolean value_) {
|
||||
const char *c_group = env->GetStringUTFChars(group_, 0);
|
||||
const char *c_key = env->GetStringUTFChars(key_, 0);
|
||||
|
||||
const QString group = QString::fromUtf8(c_group);
|
||||
const QString key = QString::fromUtf8(c_key);
|
||||
|
||||
env->ReleaseStringUTFChars(group_, c_group);
|
||||
env->ReleaseStringUTFChars(key_, c_key);
|
||||
|
||||
bool value = value_;
|
||||
|
||||
Setting::Handle<bool> setting { QStringList() << group << key , !value };
|
||||
setting.set(value);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_io_highfidelity_hifiinterface_HifiUtils_getHifiSettingBoolean(JNIEnv *env,
|
||||
jobject instance,
|
||||
jstring group_,
|
||||
jstring key_,
|
||||
jboolean defaultValue) {
|
||||
const char *c_group = env->GetStringUTFChars(group_, 0);
|
||||
const char *c_key = env->GetStringUTFChars(key_, 0);
|
||||
|
||||
const QString group = QString::fromUtf8(c_group);
|
||||
const QString key = QString::fromUtf8(c_key);
|
||||
|
||||
env->ReleaseStringUTFChars(group_, c_group);
|
||||
env->ReleaseStringUTFChars(key_, c_key);
|
||||
|
||||
Setting::Handle<bool> setting { QStringList() << group << key , defaultValue};
|
||||
return setting.get();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_io_highfidelity_hifiinterface_HifiUtils_isUserLoggedIn(JNIEnv *env, jobject instance) {
|
||||
return DependencyManager::get<AccountManager>()->isLoggedIn();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_io_highfidelity_hifiinterface_HifiUtils_isKeepingLoggedIn(JNIEnv *env, jobject instance) {
|
||||
Setting::Handle<bool> setting(AUTO_LOGOUT_SETTING_NAME, true);
|
||||
return !setting.get();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_cancelLogin(JNIEnv *env, jobject instance) {
|
||||
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
|
@ -269,17 +323,16 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeCancelLogin(JNIE
|
|||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeCancelLogin(JNIEnv *env,
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_cancelLogin(JNIEnv *env,
|
||||
jobject instance) {
|
||||
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeCancelLogin(env, instance);
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_cancelLogin(env, instance);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *env, jobject instance,
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_login(JNIEnv *env, jobject instance,
|
||||
jstring username_, jstring password_,
|
||||
jobject usernameChangedListener) {
|
||||
jboolean keepLoggedIn) {
|
||||
const char *c_username = env->GetStringUTFChars(username_, 0);
|
||||
const char *c_password = env->GetStringUTFChars(password_, 0);
|
||||
QString username = QString(c_username);
|
||||
|
@ -290,7 +343,53 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en
|
|||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
__loginCompletedListener = QAndroidJniObject(instance);
|
||||
__usernameChangedListener = QAndroidJniObject(usernameChangedListener);
|
||||
|
||||
QObject::connect(accountManager.data(), &AccountManager::loginComplete, [username, keepLoggedIn](const QUrl& authURL) {
|
||||
jboolean jSuccess = (jboolean) true;
|
||||
if (__loginCompletedListener.isValid()) {
|
||||
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
|
||||
}
|
||||
Setting::Handle<QVariant>(AUTO_LOGOUT_SETTING_NAME).set(!keepLoggedIn);
|
||||
QString usernameToSave = keepLoggedIn ? username : "";
|
||||
Setting::Handle<QVariant>(WALLET_USERNAME_SETTING_NAME).set(usernameToSave);
|
||||
});
|
||||
|
||||
QObject::connect(accountManager.data(), &AccountManager::loginFailed, []() {
|
||||
jboolean jSuccess = (jboolean) false;
|
||||
if (__loginCompletedListener.isValid()) {
|
||||
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
|
||||
}
|
||||
});
|
||||
|
||||
QMetaObject::invokeMethod(accountManager.data(), "requestAccessToken",
|
||||
Q_ARG(const QString&, username), Q_ARG(const QString&, password));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_retrieveAccessToken(JNIEnv *env,
|
||||
jobject instance,
|
||||
jstring authCode_,
|
||||
jstring clientId_,
|
||||
jstring clientSecret_,
|
||||
jstring redirectUri_) {
|
||||
const char *c_authCode = env->GetStringUTFChars(authCode_, 0);
|
||||
const char *c_clientId = env->GetStringUTFChars(clientId_, 0);
|
||||
const char *c_clientSecret = env->GetStringUTFChars(clientSecret_, 0);
|
||||
const char *c_redirectUri = env->GetStringUTFChars(redirectUri_, 0);
|
||||
|
||||
QString authCode = QString(c_authCode);
|
||||
QString clientId = QString(c_clientId);
|
||||
QString clientSecret = QString(c_clientSecret);
|
||||
QString redirectUri = QString(c_redirectUri);
|
||||
|
||||
env->ReleaseStringUTFChars(authCode_, c_authCode);
|
||||
env->ReleaseStringUTFChars(clientId_, c_clientId);
|
||||
env->ReleaseStringUTFChars(clientSecret_, c_clientSecret);
|
||||
env->ReleaseStringUTFChars(redirectUri_, c_redirectUri);
|
||||
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
__loginCompletedListener = QAndroidJniObject(instance); // TODO: use a different listener?
|
||||
|
||||
QObject::connect(accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) {
|
||||
jboolean jSuccess = (jboolean) true;
|
||||
|
@ -306,24 +405,19 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en
|
|||
}
|
||||
});
|
||||
|
||||
QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) {
|
||||
QAndroidJniObject string = QAndroidJniObject::fromString(username);
|
||||
if (__usernameChangedListener.isValid()) {
|
||||
__usernameChangedListener.callMethod<void>("handleUsernameChanged", "(Ljava/lang/String;)V", string.object<jstring>());
|
||||
}
|
||||
});
|
||||
QMetaObject::invokeMethod(accountManager.data(), "requestAccessTokenWithAuthCode",
|
||||
Q_ARG(const QString&, authCode), Q_ARG(const QString&, clientId),
|
||||
Q_ARG(const QString&, clientSecret), Q_ARG(const QString&, redirectUri));
|
||||
|
||||
QMetaObject::invokeMethod(accountManager.data(), "requestAccessToken",
|
||||
Q_ARG(const QString&, username), Q_ARG(const QString&, password));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeLogin(JNIEnv *env,
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_login(JNIEnv *env,
|
||||
jobject instance,
|
||||
jstring username_,
|
||||
jstring password_,
|
||||
jobject usernameChangedListener) {
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(env, instance, username_, password_, usernameChangedListener);
|
||||
jboolean keepLoggedIn) {
|
||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_login(env, instance, username_, password_, keepLoggedIn);
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeInitAfterAppLoaded(JNIEnv* env, jobject obj) {
|
||||
|
@ -331,7 +425,7 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeInitAf
|
|||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv *env, jobject instance,
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_signup(JNIEnv *env, jobject instance,
|
||||
jstring email_, jstring username_,
|
||||
jstring password_) {
|
||||
|
||||
|
@ -359,8 +453,6 @@ Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv *
|
|||
});
|
||||
|
||||
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, [](QString errorString) {
|
||||
jboolean jSuccess = (jboolean) false;
|
||||
jstring jError = QAndroidJniObject::fromString(errorString).object<jstring>();
|
||||
if (__signupCompletedListener.isValid()) {
|
||||
QAndroidJniObject string = QAndroidJniObject::fromString(errorString);
|
||||
__signupCompletedListener.callMethod<void>("handleSignupFailed", "(Ljava/lang/String;)V", string.object<jstring>());
|
||||
|
@ -371,19 +463,13 @@ Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv *
|
|||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeCancelSignup(JNIEnv *env, jobject instance) {
|
||||
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_cancelSignup(JNIEnv *env, jobject instance) {
|
||||
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupCompleted, nullptr, nullptr);
|
||||
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, nullptr, nullptr);
|
||||
|
||||
__signupCompletedListener = nullptr;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_FriendsFragment_nativeIsLoggedIn(JNIEnv *env, jobject instance) {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
return accountManager->isLoggedIn();
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_FriendsFragment_nativeGetAccessToken(JNIEnv *env, jobject instance) {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
@ -406,23 +492,40 @@ Java_io_highfidelity_hifiinterface_SplashActivity_registerLoadCompleteListener(J
|
|||
});
|
||||
|
||||
}
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_nativeIsLoggedIn(JNIEnv *env, jobject instance) {
|
||||
return DependencyManager::get<AccountManager>()->isLoggedIn();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_nativeLogout(JNIEnv *env, jobject instance) {
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_logout(JNIEnv *env, jobject instance) {
|
||||
DependencyManager::get<AccountManager>()->logout();
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_nativeGetDisplayName(JNIEnv *env,
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_getUsername(JNIEnv *env,
|
||||
jobject instance) {
|
||||
QString username = DependencyManager::get<AccountManager>()->getAccountInfo().getUsername();
|
||||
return env->NewStringUTF(username.toLatin1().data());
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_setUsernameChangedListener(JNIEnv *env,
|
||||
jobject instance,
|
||||
jobject usernameChangedListener) {
|
||||
__usernameChangedListener = QAndroidJniObject(usernameChangedListener);
|
||||
|
||||
if (!__usernameChangedListener.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) {
|
||||
QAndroidJniObject string = QAndroidJniObject::fromString(username);
|
||||
if (__usernameChangedListener.isValid()) {
|
||||
__usernameChangedListener.callMethod<void>("handleUsernameChanged", "(Ljava/lang/String;)V", string.object<jstring>());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeBeforeEnterBackground(JNIEnv *env, jobject obj) {
|
||||
AndroidHelper::instance().notifyBeforeEnterBackground();
|
||||
|
@ -443,46 +546,6 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_WebViewActivity_nativeProcessU
|
|||
AndroidHelper::instance().processURL(QString::fromUtf8(nativeString));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_SettingsFragment_updateHifiSetting(JNIEnv *env,
|
||||
jobject instance,
|
||||
jstring group_,
|
||||
jstring key_,
|
||||
jboolean value_) {
|
||||
const char *c_group = env->GetStringUTFChars(group_, 0);
|
||||
const char *c_key = env->GetStringUTFChars(key_, 0);
|
||||
|
||||
const QString group = QString::fromUtf8(c_group);
|
||||
const QString key = QString::fromUtf8(c_key);
|
||||
|
||||
env->ReleaseStringUTFChars(group_, c_group);
|
||||
env->ReleaseStringUTFChars(key_, c_key);
|
||||
|
||||
bool value = value_;
|
||||
|
||||
Setting::Handle<bool> setting { QStringList() << group << key , !value };
|
||||
setting.set(value);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_io_highfidelity_hifiinterface_fragment_SettingsFragment_getHifiSettingBoolean(JNIEnv *env,
|
||||
jobject instance,
|
||||
jstring group_,
|
||||
jstring key_,
|
||||
jboolean defaultValue) {
|
||||
const char *c_group = env->GetStringUTFChars(group_, 0);
|
||||
const char *c_key = env->GetStringUTFChars(key_, 0);
|
||||
|
||||
const QString group = QString::fromUtf8(c_group);
|
||||
const QString key = QString::fromUtf8(c_key);
|
||||
|
||||
env->ReleaseStringUTFChars(group_, c_group);
|
||||
env->ReleaseStringUTFChars(key_, c_key);
|
||||
|
||||
Setting::Handle<bool> setting { QStringList() << group << key , defaultValue};
|
||||
return setting.get();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_receiver_HeadsetStateReceiver_notifyHeadsetOn(JNIEnv *env,
|
||||
jobject instance,
|
||||
|
|
|
@ -64,4 +64,10 @@ public class HifiUtils {
|
|||
|
||||
public native String protocolVersionSignature();
|
||||
|
||||
public native boolean isUserLoggedIn();
|
||||
|
||||
public native void updateHifiSetting(String group, String key, boolean value);
|
||||
public native boolean getHifiSettingBoolean(String group, String key, boolean defaultValue);
|
||||
|
||||
public native boolean isKeepingLoggedIn();
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
|||
private static boolean inVrMode;
|
||||
|
||||
private boolean nativeEnterBackgroundCallEnqueued = false;
|
||||
private SlidingDrawer webSlidingDrawer;
|
||||
private SlidingDrawer mWebSlidingDrawer;
|
||||
// private GvrApi gvrApi;
|
||||
// Opaque native pointer to the Application C++ object.
|
||||
// This object is owned by the InterfaceActivity instance and passed to the native methods.
|
||||
|
@ -116,17 +116,6 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
|||
//nativeGvrApi =
|
||||
nativeOnCreate(this, assetManager /*, gvrApi.getNativeGvrContext()*/);
|
||||
|
||||
Point size = new Point();
|
||||
getWindowManager().getDefaultDisplay().getRealSize(size);
|
||||
|
||||
try {
|
||||
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
String version = pInfo.versionName;
|
||||
// setAppVersion(version);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e("GVR", "Error getting application version", e);
|
||||
}
|
||||
|
||||
final View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
|
||||
|
||||
// This is a workaround to hide the menu bar when the virtual keyboard is shown from Qt
|
||||
|
@ -137,26 +126,6 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
|||
});
|
||||
startActivity(new Intent(this, SplashActivity.class));
|
||||
mVibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
|
||||
|
||||
FrameLayout mainLayout = findViewById(android.R.id.content);
|
||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
webSlidingDrawer = (SlidingDrawer) inflater.inflate(R.layout.web_drawer, mainLayout, false);
|
||||
QtLayout qtLayout = (QtLayout) mainLayout.getChildAt(0);
|
||||
QtLayout.LayoutParams layoutParams = new QtLayout.LayoutParams(webSlidingDrawer.getLayoutParams());
|
||||
webSlidingDrawer.setOnDrawerCloseListener(() -> {
|
||||
WebViewFragment webViewFragment = (WebViewFragment) getFragmentManager().findFragmentByTag("webViewFragment");
|
||||
webViewFragment.close();
|
||||
});
|
||||
int widthPx = Math.max(size.x, size.y);
|
||||
int heightPx = Math.min(size.x, size.y);
|
||||
|
||||
layoutParams.x = (int) (widthPx - WEB_DRAWER_RIGHT_MARGIN * getResources().getDisplayMetrics().xdpi / NORMAL_DPI);
|
||||
layoutParams.y = (int) (heightPx - WEB_DRAWER_BOTTOM_MARGIN * getResources().getDisplayMetrics().ydpi / NORMAL_DPI);
|
||||
|
||||
layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
|
||||
qtLayout.addView(webSlidingDrawer, layoutParams);
|
||||
webSlidingDrawer.setVisibility(View.GONE);
|
||||
|
||||
headsetStateReceiver = new HeadsetStateReceiver();
|
||||
}
|
||||
|
||||
|
@ -289,14 +258,47 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
|||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
if (intent.hasExtra(DOMAIN_URL)) {
|
||||
webSlidingDrawer.setVisibility(View.GONE);
|
||||
hideWebDrawer();
|
||||
nativeGotoUrl(intent.getStringExtra(DOMAIN_URL));
|
||||
} else if (intent.hasExtra(EXTRA_GOTO_USERNAME)) {
|
||||
webSlidingDrawer.setVisibility(View.GONE);
|
||||
hideWebDrawer();
|
||||
nativeGoToUser(intent.getStringExtra(EXTRA_GOTO_USERNAME));
|
||||
}
|
||||
}
|
||||
|
||||
private void hideWebDrawer() {
|
||||
if (mWebSlidingDrawer != null) {
|
||||
mWebSlidingDrawer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void showWebDrawer() {
|
||||
if (mWebSlidingDrawer == null) {
|
||||
FrameLayout mainLayout = findViewById(android.R.id.content);
|
||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
QtLayout qtLayout = (QtLayout) mainLayout.getChildAt(0);
|
||||
mWebSlidingDrawer = (SlidingDrawer) inflater.inflate(R.layout.web_drawer, mainLayout, false);
|
||||
|
||||
QtLayout.LayoutParams layoutParams = new QtLayout.LayoutParams(mWebSlidingDrawer.getLayoutParams());
|
||||
mWebSlidingDrawer.setOnDrawerCloseListener(() -> {
|
||||
WebViewFragment webViewFragment = (WebViewFragment) getFragmentManager().findFragmentByTag("webViewFragment");
|
||||
webViewFragment.close();
|
||||
});
|
||||
|
||||
Point size = new Point();
|
||||
getWindowManager().getDefaultDisplay().getRealSize(size);
|
||||
int widthPx = Math.max(size.x, size.y);
|
||||
int heightPx = Math.min(size.x, size.y);
|
||||
|
||||
layoutParams.x = (int) (widthPx - WEB_DRAWER_RIGHT_MARGIN * getResources().getDisplayMetrics().xdpi / NORMAL_DPI);
|
||||
layoutParams.y = (int) (heightPx - WEB_DRAWER_BOTTOM_MARGIN * getResources().getDisplayMetrics().ydpi / NORMAL_DPI);
|
||||
|
||||
layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
|
||||
qtLayout.addView(mWebSlidingDrawer, layoutParams);
|
||||
}
|
||||
mWebSlidingDrawer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void openAndroidActivity(String activityName, boolean backToScene) {
|
||||
openAndroidActivity(activityName, backToScene, null);
|
||||
}
|
||||
|
@ -313,29 +315,29 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
|||
break;
|
||||
case "Login":
|
||||
nativeBeforeEnterBackground();
|
||||
Intent loginIntent = new Intent(this, MainActivity.class);
|
||||
loginIntent.putExtra(MainActivity.EXTRA_FRAGMENT, activityName);
|
||||
loginIntent.putExtra(MainActivity.EXTRA_BACK_TO_SCENE, backToScene);
|
||||
Intent loginIntent = new Intent(this, LoginMenuActivity.class);
|
||||
loginIntent.putExtra(LoginMenuActivity.EXTRA_BACK_TO_SCENE, backToScene);
|
||||
loginIntent.putExtra(LoginMenuActivity.EXTRA_BACK_ON_SKIP, true);
|
||||
if (args != null && args.containsKey(DOMAIN_URL)) {
|
||||
loginIntent.putExtra(DOMAIN_URL, (String) args.get(DOMAIN_URL));
|
||||
loginIntent.putExtra(LoginMenuActivity.EXTRA_DOMAIN_URL, (String) args.get(DOMAIN_URL));
|
||||
}
|
||||
startActivity(loginIntent);
|
||||
break;
|
||||
case "WebView":
|
||||
runOnUiThread(() -> {
|
||||
webSlidingDrawer.setVisibility(View.VISIBLE);
|
||||
if (!webSlidingDrawer.isOpened()) {
|
||||
webSlidingDrawer.animateOpen();
|
||||
showWebDrawer();
|
||||
if (!mWebSlidingDrawer.isOpened()) {
|
||||
mWebSlidingDrawer.animateOpen();
|
||||
}
|
||||
if (args != null && args.containsKey(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL)) {
|
||||
WebViewFragment webViewFragment = (WebViewFragment) getFragmentManager().findFragmentByTag("webViewFragment");
|
||||
webViewFragment.loadUrl((String) args.get(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL), true);
|
||||
webViewFragment.setToolbarVisible(true);
|
||||
webViewFragment.setCloseAction(() -> {
|
||||
if (webSlidingDrawer.isOpened()) {
|
||||
webSlidingDrawer.animateClose();
|
||||
if (mWebSlidingDrawer.isOpened()) {
|
||||
mWebSlidingDrawer.animateClose();
|
||||
}
|
||||
webSlidingDrawer.setVisibility(View.GONE);
|
||||
hideWebDrawer();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -381,4 +383,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
|||
public void onExpand() {
|
||||
keepInterfaceRunning = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOAuthAuthorizeCallback(Uri uri) { }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
package io.highfidelity.hifiinterface;
|
||||
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import io.highfidelity.hifiinterface.fragment.LoginFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.OnBackPressedListener;
|
||||
import io.highfidelity.hifiinterface.fragment.SignupFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.StartMenuFragment;
|
||||
|
||||
public class LoginMenuActivity extends AppCompatActivity
|
||||
implements StartMenuFragment.StartMenuInteractionListener,
|
||||
LoginFragment.OnLoginInteractionListener,
|
||||
SignupFragment.OnSignupInteractionListener {
|
||||
|
||||
/**
|
||||
* Set EXTRA_FINISH_ON_BACK to finish the app when back button is pressed
|
||||
*/
|
||||
public static final String EXTRA_FINISH_ON_BACK = "finishOnBack";
|
||||
|
||||
/**
|
||||
* Set EXTRA_BACK_TO_SCENE to back to the scene
|
||||
*/
|
||||
public static final String EXTRA_BACK_TO_SCENE = "backToScene";
|
||||
|
||||
/**
|
||||
* Set EXTRA_BACK_ON_SKIP to finish this activity when skip button is pressed
|
||||
*/
|
||||
public static final String EXTRA_BACK_ON_SKIP = "backOnSkip";
|
||||
|
||||
public static final String EXTRA_DOMAIN_URL = "url";
|
||||
|
||||
private boolean finishOnBack;
|
||||
private boolean backToScene;
|
||||
private boolean backOnSkip;
|
||||
private String domainUrlToBack;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_encourage_login);
|
||||
|
||||
finishOnBack = getIntent().getBooleanExtra(EXTRA_FINISH_ON_BACK, false);
|
||||
backToScene = getIntent().getBooleanExtra(EXTRA_BACK_TO_SCENE, false);
|
||||
domainUrlToBack = getIntent().getStringExtra(EXTRA_DOMAIN_URL);
|
||||
backOnSkip = getIntent().getBooleanExtra(EXTRA_BACK_ON_SKIP, false);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
finishOnBack = savedInstanceState.getBoolean(EXTRA_FINISH_ON_BACK, false);
|
||||
backToScene = savedInstanceState.getBoolean(EXTRA_BACK_TO_SCENE, false);
|
||||
backOnSkip = savedInstanceState.getBoolean(EXTRA_BACK_ON_SKIP, false);
|
||||
domainUrlToBack = savedInstanceState.getString(EXTRA_DOMAIN_URL);
|
||||
}
|
||||
|
||||
loadMenuFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(EXTRA_FINISH_ON_BACK, finishOnBack);
|
||||
outState.putBoolean(EXTRA_BACK_TO_SCENE, backToScene);
|
||||
outState.putString(EXTRA_DOMAIN_URL, domainUrlToBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
finishOnBack = savedInstanceState.getBoolean(EXTRA_FINISH_ON_BACK, false);
|
||||
backToScene = savedInstanceState.getBoolean(EXTRA_BACK_TO_SCENE, false);
|
||||
backOnSkip = savedInstanceState.getBoolean(EXTRA_BACK_ON_SKIP, false);
|
||||
domainUrlToBack = savedInstanceState.getString(EXTRA_DOMAIN_URL);
|
||||
}
|
||||
|
||||
private void loadMenuFragment() {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
Fragment fragment = StartMenuFragment.newInstance();
|
||||
fragmentTransaction.replace(R.id.content_frame, fragment);
|
||||
fragmentTransaction.addToBackStack(fragment.toString());
|
||||
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
||||
fragmentTransaction.commit();
|
||||
hideStatusBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
hideStatusBar();
|
||||
}
|
||||
|
||||
private void hideStatusBar() {
|
||||
View decorView = getWindow().getDecorView();
|
||||
// Hide the status bar.
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||
decorView.setSystemUiVisibility(uiOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignupButtonClicked() {
|
||||
loadSignupFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoginButtonClicked() {
|
||||
loadLoginFragment(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSkipLoginClicked() {
|
||||
if (backOnSkip) {
|
||||
onBackPressed();
|
||||
} else {
|
||||
loadMainActivity();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSteamLoginButtonClicked() {
|
||||
loadLoginFragment(true);
|
||||
}
|
||||
|
||||
private void loadSignupFragment() {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
Fragment fragment = SignupFragment.newInstance();
|
||||
String tag = getString(R.string.tagFragmentSignup);
|
||||
fragmentTransaction.replace(R.id.content_frame, fragment, tag);
|
||||
fragmentTransaction.addToBackStack(tag);
|
||||
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
||||
fragmentTransaction.commit();
|
||||
hideStatusBar();
|
||||
}
|
||||
|
||||
private void loadLoginFragment(boolean useOauth) {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
Fragment fragment = LoginFragment.newInstance(useOauth);
|
||||
String tag = getString(R.string.tagFragmentLogin);
|
||||
fragmentTransaction.replace(R.id.content_frame, fragment, tag);
|
||||
fragmentTransaction.addToBackStack(tag);
|
||||
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
||||
fragmentTransaction.commit();
|
||||
hideStatusBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoginCompleted() {
|
||||
loadMainActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelLogin() {
|
||||
getFragmentManager().popBackStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelSignup() {
|
||||
getFragmentManager().popBackStack();
|
||||
}
|
||||
|
||||
private void loadMainActivity() {
|
||||
finish();
|
||||
if (backToScene) {
|
||||
backToScene = false;
|
||||
goToDomain(domainUrlToBack != null? domainUrlToBack : "");
|
||||
} else {
|
||||
startActivity(new Intent(this, MainActivity.class));
|
||||
}
|
||||
}
|
||||
|
||||
private void goToDomain(String domainUrl) {
|
||||
Intent intent = new Intent(this, InterfaceActivity.class);
|
||||
intent.putExtra(InterfaceActivity.DOMAIN_URL, domainUrl);
|
||||
finish();
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSignupCompleted() {
|
||||
loadMainActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
FragmentManager fm = getFragmentManager();
|
||||
int index = fm.getBackStackEntryCount() - 1;
|
||||
if (index > 0) {
|
||||
FragmentManager.BackStackEntry backEntry = fm.getBackStackEntryAt(index);
|
||||
String tag = backEntry.getName();
|
||||
Fragment topFragment = getFragmentManager().findFragmentByTag(tag);
|
||||
if (!(topFragment instanceof OnBackPressedListener) ||
|
||||
!((OnBackPressedListener) topFragment).doBack()) {
|
||||
super.onBackPressed();
|
||||
}
|
||||
} else if (finishOnBack){
|
||||
finishAffinity();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package io.highfidelity.hifiinterface;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
|
@ -29,23 +30,16 @@ import android.widget.TextView;
|
|||
import com.squareup.picasso.Callback;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.highfidelity.hifiinterface.fragment.FriendsFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.HomeFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.LoginFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.PolicyFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.SettingsFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.SignedInFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.SignupFragment;import io.highfidelity.hifiinterface.task.DownloadProfileImageTask;
|
||||
import io.highfidelity.hifiinterface.fragment.SignupFragment;
|
||||
import io.highfidelity.hifiinterface.task.DownloadProfileImageTask;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
|
||||
LoginFragment.OnLoginInteractionListener,
|
||||
HomeFragment.OnHomeInteractionListener,
|
||||
FriendsFragment.OnHomeInteractionListener,
|
||||
SignupFragment.OnSignupInteractionListener,
|
||||
SignedInFragment.OnSignedInInteractionListener {
|
||||
FriendsFragment.OnHomeInteractionListener {
|
||||
|
||||
private static final int PROFILE_PICTURE_PLACEHOLDER = R.drawable.default_profile_avatar;
|
||||
public static final String DEFAULT_FRAGMENT = "Home";
|
||||
|
@ -55,9 +49,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
|
||||
private String TAG = "HighFidelity";
|
||||
|
||||
public native boolean nativeIsLoggedIn();
|
||||
public native void nativeLogout();
|
||||
public native String nativeGetDisplayName();
|
||||
public native void logout();
|
||||
public native void setUsernameChangedListener(Activity usernameChangedListener);
|
||||
public native String getUsername();
|
||||
|
||||
private DrawerLayout mDrawerLayout;
|
||||
private NavigationView mNavigationView;
|
||||
|
@ -130,9 +124,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
|
||||
private void loadFragment(String fragment) {
|
||||
switch (fragment) {
|
||||
case "Login":
|
||||
loadLoginFragment();
|
||||
break;
|
||||
case "Home":
|
||||
loadHomeFragment(true);
|
||||
break;
|
||||
|
@ -153,19 +144,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
loadFragment(fragment, getString(R.string.home), getString(R.string.tagFragmentHome), addToBackStack, true);
|
||||
}
|
||||
|
||||
private void loadLoginFragment() {
|
||||
Fragment fragment = LoginFragment.newInstance();
|
||||
loadFragment(fragment, getString(R.string.login), getString(R.string.tagFragmentLogin), true, true);
|
||||
}
|
||||
|
||||
private void loadSignedInFragment() {
|
||||
Fragment fragment = SignedInFragment.newInstance();
|
||||
loadFragment(fragment, getString(R.string.welcome), getString(R.string.tagFragmentSignedIn), true, true);
|
||||
}
|
||||
|
||||
private void loadSignupFragment() {
|
||||
Fragment fragment = SignupFragment.newInstance();
|
||||
loadFragment(fragment, getString(R.string.signup), getString(R.string.tagFragmentSignup), true, false);
|
||||
private void startLoginMenuActivity() {
|
||||
Intent intent = new Intent(this, LoginMenuActivity.class);
|
||||
intent.putExtra(LoginMenuActivity.EXTRA_BACK_ON_SKIP, true);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void loadPrivacyPolicyFragment() {
|
||||
|
@ -223,7 +205,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
|
||||
|
||||
private void updateLoginMenu() {
|
||||
if (nativeIsLoggedIn()) {
|
||||
if (HifiUtils.getInstance().isUserLoggedIn()) {
|
||||
mLoginPanel.setVisibility(View.GONE);
|
||||
mProfilePanel.setVisibility(View.VISIBLE);
|
||||
mLogoutOption.setVisibility(View.VISIBLE);
|
||||
|
@ -239,7 +221,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
}
|
||||
|
||||
private void updateProfileHeader() {
|
||||
updateProfileHeader(nativeGetDisplayName());
|
||||
updateProfileHeader(getUsername());
|
||||
}
|
||||
private void updateProfileHeader(String username) {
|
||||
if (!username.isEmpty()) {
|
||||
|
@ -289,15 +271,22 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
setUsernameChangedListener(this);
|
||||
updateLoginMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
setUsernameChangedListener(null);
|
||||
}
|
||||
|
||||
public void onLoginClicked(View view) {
|
||||
loadLoginFragment();
|
||||
startLoginMenuActivity();
|
||||
}
|
||||
|
||||
public void onLogoutClicked(View view) {
|
||||
nativeLogout();
|
||||
logout();
|
||||
updateLoginMenu();
|
||||
exitLoggedInFragment();
|
||||
|
||||
|
@ -338,42 +327,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoginCompleted() {
|
||||
loadHomeFragment(false);
|
||||
updateLoginMenu();
|
||||
if (backToScene) {
|
||||
backToScene = false;
|
||||
goToLastLocation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGettingStarted() {
|
||||
loadHomeFragment(false);
|
||||
if (backToScene) {
|
||||
backToScene = false;
|
||||
goToLastLocation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoginRequested() {
|
||||
// go back from signup to login
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignupRequested() {
|
||||
loadSignupFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignupCompleted() {
|
||||
loadSignedInFragment();
|
||||
updateLoginMenu();
|
||||
}
|
||||
|
||||
public void handleUsernameChanged(String username) {
|
||||
runOnUiThread(() -> updateProfileHeader(username));
|
||||
}
|
||||
|
@ -418,7 +371,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
public void onBackPressed() {
|
||||
// if a fragment needs to internally manage back presses..
|
||||
FragmentManager fm = getFragmentManager();
|
||||
Log.d("[BACK]", "getBackStackEntryCount " + fm.getBackStackEntryCount());
|
||||
Fragment friendsFragment = fm.findFragmentByTag(getString(R.string.tagFragmentPeople));
|
||||
if (friendsFragment != null && friendsFragment instanceof FriendsFragment) {
|
||||
if (((FriendsFragment) friendsFragment).onBackPressed()) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.highfidelity.hifiinterface;
|
|||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
|
||||
public class SplashActivity extends Activity {
|
||||
|
@ -37,7 +36,13 @@ public class SplashActivity extends Activity {
|
|||
}
|
||||
|
||||
public void onAppLoadedComplete() {
|
||||
startActivity(new Intent(this, MainActivity.class));
|
||||
if (HifiUtils.getInstance().isUserLoggedIn()) {
|
||||
startActivity(new Intent(this, MainActivity.class));
|
||||
} else {
|
||||
Intent menuIntent = new Intent(this, LoginMenuActivity.class);
|
||||
menuIntent.putExtra(LoginMenuActivity.EXTRA_FINISH_ON_BACK, true);
|
||||
startActivity(menuIntent);
|
||||
}
|
||||
SplashActivity.this.finish();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,18 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
|
||||
import io.highfidelity.hifiinterface.fragment.WebViewFragment;
|
||||
import io.highfidelity.hifiinterface.fragment.WebViewFragment.OnWebViewInteractionListener;
|
||||
|
||||
public class WebViewActivity extends Activity implements WebViewFragment.OnWebViewInteractionListener {
|
||||
public class WebViewActivity extends Activity implements OnWebViewInteractionListener {
|
||||
|
||||
public static final String WEB_VIEW_ACTIVITY_EXTRA_URL = "url";
|
||||
public static final String WEB_VIEW_ACTIVITY_EXTRA_CLEAR_COOKIES = "clear_cookies";
|
||||
public static final String RESULT_OAUTH_CODE = "code";
|
||||
public static final String RESULT_OAUTH_STATE = "state";
|
||||
|
||||
private static final String FRAGMENT_TAG = "WebViewActivity_WebFragment";
|
||||
private static final String OAUTH_CODE = "code";
|
||||
private static final String OAUTH_STATE = "state";
|
||||
|
||||
private native void nativeProcessURL(String url);
|
||||
|
||||
|
@ -47,14 +54,15 @@ public class WebViewActivity extends Activity implements WebViewFragment.OnWebVi
|
|||
mActionBar = getActionBar();
|
||||
mActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
loadWebViewFragment(getIntent().getStringExtra(WEB_VIEW_ACTIVITY_EXTRA_URL));
|
||||
loadWebViewFragment(getIntent().getStringExtra(WEB_VIEW_ACTIVITY_EXTRA_URL), getIntent().getBooleanExtra(WEB_VIEW_ACTIVITY_EXTRA_CLEAR_COOKIES, false));
|
||||
}
|
||||
|
||||
private void loadWebViewFragment(String url) {
|
||||
private void loadWebViewFragment(String url, boolean clearCookies) {
|
||||
WebViewFragment fragment = WebViewFragment.newInstance();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(WebViewFragment.URL, url);
|
||||
bundle.putBoolean(WebViewFragment.TOOLBAR_VISIBLE, false);
|
||||
bundle.putBoolean(WebViewFragment.CLEAR_COOKIES, clearCookies);
|
||||
fragment.setArguments(bundle);
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
FragmentTransaction ft = fragmentManager.beginTransaction();
|
||||
|
@ -131,4 +139,13 @@ public class WebViewActivity extends Activity implements WebViewFragment.OnWebVi
|
|||
@Override
|
||||
public void onExpand() { }
|
||||
|
||||
@Override
|
||||
public void onOAuthAuthorizeCallback(Uri uri) {
|
||||
Intent result = new Intent();
|
||||
result.putExtra(RESULT_OAUTH_CODE, uri.getQueryParameter(OAUTH_CODE));
|
||||
result.putExtra(RESULT_OAUTH_STATE, uri.getQueryParameter(OAUTH_STATE));
|
||||
setResult(Activity.RESULT_OK, result);
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@ import io.highfidelity.hifiinterface.view.UserListAdapter;
|
|||
|
||||
public class FriendsFragment extends Fragment {
|
||||
|
||||
public native boolean nativeIsLoggedIn();
|
||||
|
||||
public native String nativeGetAccessToken();
|
||||
|
||||
private RecyclerView mUsersView;
|
||||
|
|
|
@ -2,41 +2,65 @@ package io.highfidelity.hifiinterface.fragment;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.qtproject.qt5.android.QtNative;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Random;
|
||||
|
||||
import io.highfidelity.hifiinterface.BuildConfig;
|
||||
import io.highfidelity.hifiinterface.HifiUtils;
|
||||
import io.highfidelity.hifiinterface.R;
|
||||
import io.highfidelity.hifiinterface.WebViewActivity;
|
||||
|
||||
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationActive;
|
||||
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationInactive;
|
||||
|
||||
public class LoginFragment extends Fragment {
|
||||
public class LoginFragment extends Fragment
|
||||
implements OnBackPressedListener {
|
||||
|
||||
private static final String ARG_USE_OAUTH = "use_oauth";
|
||||
private static final String TAG = "Interface";
|
||||
|
||||
private final String OAUTH_CLIENT_ID = BuildConfig.OAUTH_CLIENT_ID;
|
||||
private final String OAUTH_REDIRECT_URI = BuildConfig.OAUTH_REDIRECT_URI;
|
||||
private final String OAUTH_AUTHORIZE_BASE_URL = "https://highfidelity.com/oauth/authorize";
|
||||
private static final int OAUTH_AUTHORIZE_REQUEST = 1;
|
||||
|
||||
private EditText mUsername;
|
||||
private EditText mPassword;
|
||||
private TextView mError;
|
||||
private TextView mForgotPassword;
|
||||
private TextView mSignup;
|
||||
private Button mLoginButton;
|
||||
private CheckBox mKeepMeLoggedInCheckbox;
|
||||
private ViewGroup mLoginForm;
|
||||
private ViewGroup mLoggingInFrame;
|
||||
private ViewGroup mLoggedInFrame;
|
||||
private boolean mLoginInProgress;
|
||||
private boolean mLoginSuccess;
|
||||
private boolean mUseOauth;
|
||||
private String mOauthState;
|
||||
|
||||
private ProgressDialog mDialog;
|
||||
public native void login(String username, String password, boolean keepLoggedIn);
|
||||
private native void retrieveAccessToken(String authCode, String clientId, String clientSecret, String redirectUri);
|
||||
|
||||
public native void nativeLogin(String username, String password, Activity usernameChangedListener);
|
||||
public native void nativeCancelLogin();
|
||||
public native void cancelLogin();
|
||||
|
||||
private LoginFragment.OnLoginInteractionListener mListener;
|
||||
|
||||
|
@ -44,11 +68,22 @@ public class LoginFragment extends Fragment {
|
|||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static LoginFragment newInstance() {
|
||||
public static LoginFragment newInstance(boolean useOauth) {
|
||||
LoginFragment fragment = new LoginFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putBoolean(ARG_USE_OAUTH, useOauth);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
mUseOauth = getArguments().getBoolean(ARG_USE_OAUTH, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
@ -58,22 +93,29 @@ public class LoginFragment extends Fragment {
|
|||
mPassword = rootView.findViewById(R.id.password);
|
||||
mError = rootView.findViewById(R.id.error);
|
||||
mLoginButton = rootView.findViewById(R.id.loginButton);
|
||||
mForgotPassword = rootView.findViewById(R.id.forgotPassword);
|
||||
mSignup = rootView.findViewById(R.id.signupButton);
|
||||
mLoginForm = rootView.findViewById(R.id.loginForm);
|
||||
mLoggingInFrame = rootView.findViewById(R.id.loggingInFrame);
|
||||
mLoggedInFrame = rootView.findViewById(R.id.loggedInFrame);
|
||||
mKeepMeLoggedInCheckbox = rootView.findViewById(R.id.keepMeLoggedIn);
|
||||
|
||||
mLoginButton.setOnClickListener(view -> login());
|
||||
rootView.findViewById(R.id.forgotPassword).setOnClickListener(view -> onForgotPasswordClicked());
|
||||
|
||||
mForgotPassword.setOnClickListener(view -> forgotPassword());
|
||||
mSignup.setOnClickListener(view -> signup());
|
||||
rootView.findViewById(R.id.cancel).setOnClickListener(view -> onCancelLogin());
|
||||
|
||||
mPassword.setOnEditorActionListener(
|
||||
(textView, actionId, keyEvent) -> {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
mLoginButton.performClick();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
rootView.findViewById(R.id.getStarted).setOnClickListener(view -> onGetStartedClicked());
|
||||
|
||||
mLoginButton.setOnClickListener(view -> onLoginButtonClicked());
|
||||
|
||||
rootView.findViewById(R.id.takeMeInWorld).setOnClickListener(view -> skipLogin());
|
||||
mPassword.setOnEditorActionListener((textView, actionId, keyEvent) -> onPasswordEditorAction(textView, actionId, keyEvent));
|
||||
|
||||
mKeepMeLoggedInCheckbox.setChecked(HifiUtils.getInstance().isKeepingLoggedIn());
|
||||
|
||||
if (mUseOauth) {
|
||||
openWebForAuthorization();
|
||||
} else {
|
||||
showLoginForm();
|
||||
}
|
||||
return rootView;
|
||||
}
|
||||
|
||||
|
@ -104,13 +146,57 @@ public class LoginFragment extends Fragment {
|
|||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
cancelActivityIndicator();
|
||||
// Leave the Qt app paused
|
||||
QtNative.setApplicationState(ApplicationInactive);
|
||||
hideKeyboard();
|
||||
}
|
||||
|
||||
public void login() {
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == OAUTH_AUTHORIZE_REQUEST) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
String authCode = data.getStringExtra(WebViewActivity.RESULT_OAUTH_CODE);
|
||||
String state = data.getStringExtra(WebViewActivity.RESULT_OAUTH_STATE);
|
||||
if (state != null && state.equals(mOauthState) && mListener != null) {
|
||||
mOauthState = null;
|
||||
showActivityIndicator();
|
||||
mLoginInProgress = true;
|
||||
retrieveAccessToken(authCode, BuildConfig.OAUTH_CLIENT_ID, BuildConfig.OAUTH_CLIENT_SECRET, BuildConfig.OAUTH_REDIRECT_URI);
|
||||
}
|
||||
} else {
|
||||
onCancelLogin();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onCancelLogin() {
|
||||
if (mListener != null) {
|
||||
mListener.onCancelLogin();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onPasswordEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
mLoginButton.performClick();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void skipLogin() {
|
||||
if (mListener != null) {
|
||||
mListener.onSkipLoginClicked();
|
||||
}
|
||||
}
|
||||
|
||||
private void onGetStartedClicked() {
|
||||
if (mListener != null) {
|
||||
mListener.onLoginCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
public void onLoginButtonClicked() {
|
||||
String username = mUsername.getText().toString().trim();
|
||||
String password = mPassword.getText().toString();
|
||||
hideKeyboard();
|
||||
|
@ -120,13 +206,10 @@ public class LoginFragment extends Fragment {
|
|||
mLoginButton.setEnabled(false);
|
||||
hideError();
|
||||
showActivityIndicator();
|
||||
nativeLogin(username, password, getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
public void signup() {
|
||||
if (mListener != null) {
|
||||
mListener.onSignupRequested();
|
||||
mLoginInProgress = true;
|
||||
mLoginSuccess = false;
|
||||
boolean keepUserLoggedIn = mKeepMeLoggedInCheckbox.isChecked();
|
||||
login(username, password, keepUserLoggedIn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,33 +221,32 @@ public class LoginFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void forgotPassword() {
|
||||
private void onForgotPasswordClicked() {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://highfidelity.com/users/password/new"));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void showActivityIndicator() {
|
||||
if (mDialog == null) {
|
||||
mDialog = new ProgressDialog(getContext());
|
||||
}
|
||||
mDialog.setMessage(getString(R.string.logging_in));
|
||||
mDialog.setCancelable(true);
|
||||
mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialogInterface) {
|
||||
nativeCancelLogin();
|
||||
cancelActivityIndicator();
|
||||
mLoginButton.setEnabled(true);
|
||||
}
|
||||
});
|
||||
mDialog.show();
|
||||
mLoginForm.setVisibility(View.GONE);
|
||||
mLoggedInFrame.setVisibility(View.GONE);
|
||||
mLoggingInFrame.setVisibility(View.VISIBLE);
|
||||
mLoggingInFrame.bringToFront();
|
||||
}
|
||||
|
||||
private void cancelActivityIndicator() {
|
||||
if (mDialog != null) {
|
||||
mDialog.cancel();
|
||||
}
|
||||
private void showLoginForm() {
|
||||
mLoggingInFrame.setVisibility(View.GONE);
|
||||
mLoggedInFrame.setVisibility(View.GONE);
|
||||
mLoginForm.setVisibility(View.VISIBLE);
|
||||
mLoginForm.bringToFront();
|
||||
}
|
||||
|
||||
private void showLoggedInMessage() {
|
||||
mLoginForm.setVisibility(View.GONE);
|
||||
mLoggingInFrame.setVisibility(View.GONE);
|
||||
mLoggedInFrame.setVisibility(View.VISIBLE);
|
||||
mLoggedInFrame.bringToFront();
|
||||
}
|
||||
|
||||
private void showError(String error) {
|
||||
mError.setText(error);
|
||||
mError.setVisibility(View.VISIBLE);
|
||||
|
@ -176,22 +258,71 @@ public class LoginFragment extends Fragment {
|
|||
}
|
||||
|
||||
public void handleLoginCompleted(boolean success) {
|
||||
mLoginInProgress = false;
|
||||
getActivity().runOnUiThread(() -> {
|
||||
mLoginButton.setEnabled(true);
|
||||
cancelActivityIndicator();
|
||||
if (success) {
|
||||
if (mListener != null) {
|
||||
mListener.onLoginCompleted();
|
||||
}
|
||||
mLoginSuccess = true;
|
||||
showLoggedInMessage();
|
||||
} else {
|
||||
showError(getString(R.string.login_username_or_password_incorrect));
|
||||
if (!mUseOauth) {
|
||||
showLoginForm();
|
||||
showError(getString(R.string.login_username_or_password_incorrect));
|
||||
} else {
|
||||
openWebForAuthorization();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doBack() {
|
||||
if (mLoginInProgress) {
|
||||
cancelLogin();
|
||||
showLoginForm();
|
||||
mLoginInProgress = false;
|
||||
mLoginButton.setEnabled(true);
|
||||
return true;
|
||||
} else if (mLoginSuccess) {
|
||||
onGetStartedClicked();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOauthState() {
|
||||
// as we only use oauth for steam that's ok for now
|
||||
mOauthState = "steam-" + Long.toString(new Random().nextLong());
|
||||
}
|
||||
|
||||
private String buildAuthorizeUrl() {
|
||||
StringBuilder sb = new StringBuilder(OAUTH_AUTHORIZE_BASE_URL);
|
||||
sb.append("?client_id=").append(OAUTH_CLIENT_ID);
|
||||
try {
|
||||
String redirectUri = URLEncoder.encode(OAUTH_REDIRECT_URI, "utf-8");
|
||||
sb.append("&redirect_uri=").append(redirectUri);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Log.e(TAG, "Cannot build oauth autorization url", e);
|
||||
}
|
||||
sb.append("&response_type=code&scope=owner");
|
||||
sb.append("&state=").append(mOauthState);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void openWebForAuthorization() {
|
||||
Intent openUrlIntent = new Intent(getActivity(), WebViewActivity.class);
|
||||
updateOauthState();
|
||||
openUrlIntent.putExtra(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL, buildAuthorizeUrl());
|
||||
openUrlIntent.putExtra(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_CLEAR_COOKIES, true);
|
||||
startActivityForResult(openUrlIntent, OAUTH_AUTHORIZE_REQUEST);
|
||||
}
|
||||
|
||||
|
||||
public interface OnLoginInteractionListener {
|
||||
void onLoginCompleted();
|
||||
void onSignupRequested();
|
||||
void onCancelLogin();
|
||||
void onSkipLoginClicked();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package io.highfidelity.hifiinterface.fragment;
|
||||
|
||||
public interface OnBackPressedListener {
|
||||
|
||||
/**
|
||||
* Processes the back pressed event and returns true if it was managed by this Fragment
|
||||
* @return
|
||||
*/
|
||||
boolean doBack();
|
||||
|
||||
}
|
|
@ -3,32 +3,35 @@ package io.highfidelity.hifiinterface.fragment;
|
|||
import android.content.SharedPreferences;
|
||||
import android.media.audiofx.AcousticEchoCanceler;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import io.highfidelity.hifiinterface.HifiUtils;
|
||||
import io.highfidelity.hifiinterface.R;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
public native void updateHifiSetting(String group, String key, boolean value);
|
||||
public native boolean getHifiSettingBoolean(String group, String key, boolean defaultValue);
|
||||
|
||||
private final String HIFI_SETTINGS_ANDROID_GROUP = "Android";
|
||||
private final String HIFI_SETTINGS_AEC_KEY = "aec";
|
||||
private final String PREFERENCE_KEY_AEC = "aec";
|
||||
|
||||
private final boolean DEFAULT_AEC_ENABLED = true;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.settings);
|
||||
boolean aecAvailable = AcousticEchoCanceler.isAvailable();
|
||||
PreferenceManager.setDefaultValues(getContext(), R.xml.settings, false);
|
||||
|
||||
if (!AcousticEchoCanceler.isAvailable()) {
|
||||
getPreferenceScreen().getPreferenceManager().findPreference("aec").setEnabled(false);
|
||||
if (!aecAvailable) {
|
||||
findPreference(PREFERENCE_KEY_AEC).setEnabled(false);
|
||||
HifiUtils.getInstance().updateHifiSetting(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, false);
|
||||
}
|
||||
|
||||
getPreferenceScreen().getSharedPreferences().edit().putBoolean(PREFERENCE_KEY_AEC,
|
||||
getHifiSettingBoolean(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, false));
|
||||
aecAvailable && HifiUtils.getInstance().getHifiSettingBoolean(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, DEFAULT_AEC_ENABLED)).commit();
|
||||
}
|
||||
|
||||
public static SettingsFragment newInstance() {
|
||||
|
@ -46,15 +49,13 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer
|
|||
public void onPause() {
|
||||
super.onPause();
|
||||
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
Preference pref = findPreference(key);
|
||||
switch (key) {
|
||||
case "aec":
|
||||
updateHifiSetting(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, sharedPreferences.getBoolean(key, false));
|
||||
HifiUtils.getInstance().updateHifiSetting(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, sharedPreferences.getBoolean(key, false));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
package io.highfidelity.hifiinterface.fragment;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import io.highfidelity.hifiinterface.R;
|
||||
|
||||
public class SignedInFragment extends Fragment {
|
||||
|
||||
private Button mGetStartedButton;
|
||||
private OnSignedInInteractionListener mListener;
|
||||
|
||||
public SignedInFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static SignedInFragment newInstance() {
|
||||
SignedInFragment fragment = new SignedInFragment();
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_signedin, container, false);
|
||||
mGetStartedButton = rootView.findViewById(R.id.getStarted);
|
||||
|
||||
mGetStartedButton.setOnClickListener(view -> {
|
||||
getStarted();
|
||||
});
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof SignedInFragment.OnSignedInInteractionListener) {
|
||||
mListener = (SignedInFragment.OnSignedInInteractionListener) context;
|
||||
} else {
|
||||
throw new RuntimeException(context.toString()
|
||||
+ " must implement OnSignedInInteractionListener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
public void getStarted() {
|
||||
if (mListener != null) {
|
||||
mListener.onGettingStarted();
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnSignedInInteractionListener {
|
||||
void onGettingStarted();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +1,50 @@
|
|||
package io.highfidelity.hifiinterface.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.qtproject.qt5.android.QtNative;
|
||||
|
||||
import io.highfidelity.hifiinterface.HifiUtils;
|
||||
import io.highfidelity.hifiinterface.R;
|
||||
|
||||
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationActive;
|
||||
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationInactive;
|
||||
|
||||
public class SignupFragment extends Fragment {
|
||||
public class SignupFragment extends Fragment
|
||||
implements OnBackPressedListener {
|
||||
|
||||
private EditText mEmail;
|
||||
private EditText mUsername;
|
||||
private EditText mPassword;
|
||||
private TextView mError;
|
||||
private TextView mCancelButton;
|
||||
|
||||
private TextView mActivityText;
|
||||
private Button mSignupButton;
|
||||
private CheckBox mKeepMeLoggedInCheckbox;
|
||||
|
||||
private ProgressDialog mDialog;
|
||||
private ViewGroup mSignupForm;
|
||||
private ViewGroup mLoggingInFrame;
|
||||
private ViewGroup mLoggedInFrame;
|
||||
|
||||
public native void nativeSignup(String email, String username, String password); // move to SignupFragment
|
||||
public native void nativeCancelSignup();
|
||||
public native void nativeLogin(String username, String password, Activity usernameChangedListener);
|
||||
public native void nativeCancelLogin();
|
||||
private boolean mLoginInProgress;
|
||||
private boolean mSignupInProgress;
|
||||
private boolean mSignupSuccess;
|
||||
|
||||
public native void signup(String email, String username, String password); // move to SignupFragment
|
||||
public native void cancelSignup();
|
||||
public native void login(String username, String password, boolean keepLoggedIn);
|
||||
public native void cancelLogin();
|
||||
|
||||
private SignupFragment.OnSignupInteractionListener mListener;
|
||||
|
||||
|
@ -59,18 +67,23 @@ public class SignupFragment extends Fragment {
|
|||
mPassword = rootView.findViewById(R.id.password);
|
||||
mError = rootView.findViewById(R.id.error);
|
||||
mSignupButton = rootView.findViewById(R.id.signupButton);
|
||||
mCancelButton = rootView.findViewById(R.id.cancelButton);
|
||||
mActivityText = rootView.findViewById(R.id.activityText);
|
||||
mKeepMeLoggedInCheckbox = rootView.findViewById(R.id.keepMeLoggedIn);
|
||||
|
||||
mSignupForm = rootView.findViewById(R.id.signupForm);
|
||||
mLoggedInFrame = rootView.findViewById(R.id.loggedInFrame);
|
||||
mLoggingInFrame = rootView.findViewById(R.id.loggingInFrame);
|
||||
|
||||
rootView.findViewById(R.id.cancel).setOnClickListener(view -> onCancelSignup());
|
||||
|
||||
mSignupButton.setOnClickListener(view -> signup());
|
||||
mCancelButton.setOnClickListener(view -> login());
|
||||
mPassword.setOnEditorActionListener(
|
||||
(textView, actionId, keyEvent) -> {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
mSignupButton.performClick();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
rootView.findViewById(R.id.getStarted).setOnClickListener(view -> onGetStartedClicked());
|
||||
|
||||
mPassword.setOnEditorActionListener((textView, actionId, keyEvent) -> onPasswordEditorAction(textView, actionId, keyEvent));
|
||||
|
||||
mKeepMeLoggedInCheckbox.setChecked(HifiUtils.getInstance().isKeepingLoggedIn());
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
|
@ -101,15 +114,22 @@ public class SignupFragment extends Fragment {
|
|||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
cancelActivityIndicator();
|
||||
// Leave the Qt app paused
|
||||
QtNative.setApplicationState(ApplicationInactive);
|
||||
hideKeyboard();
|
||||
}
|
||||
|
||||
private void login() {
|
||||
private boolean onPasswordEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
mSignupButton.performClick();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void onCancelSignup() {
|
||||
if (mListener != null) {
|
||||
mListener.onLoginRequested();
|
||||
mListener.onCancelSignup();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,8 +143,11 @@ public class SignupFragment extends Fragment {
|
|||
} else {
|
||||
mSignupButton.setEnabled(false);
|
||||
hideError();
|
||||
mActivityText.setText(R.string.creating_account);
|
||||
showActivityIndicator();
|
||||
nativeSignup(email, username, password);
|
||||
mSignupInProgress = true;
|
||||
mSignupSuccess = false;
|
||||
signup(email, username, password);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,23 +160,21 @@ public class SignupFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void showActivityIndicator() {
|
||||
if (mDialog == null) {
|
||||
mDialog = new ProgressDialog(getContext());
|
||||
}
|
||||
mDialog.setMessage(getString(R.string.creating_account));
|
||||
mDialog.setCancelable(true);
|
||||
mDialog.setOnCancelListener(dialogInterface -> {
|
||||
nativeCancelSignup();
|
||||
cancelActivityIndicator();
|
||||
mSignupButton.setEnabled(true);
|
||||
});
|
||||
mDialog.show();
|
||||
mSignupForm.setVisibility(View.GONE);
|
||||
mLoggedInFrame.setVisibility(View.GONE);
|
||||
mLoggingInFrame.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void cancelActivityIndicator() {
|
||||
if (mDialog != null) {
|
||||
mDialog.cancel();
|
||||
}
|
||||
private void showLoggedInMessage() {
|
||||
mSignupForm.setVisibility(View.GONE);
|
||||
mLoggingInFrame.setVisibility(View.GONE);
|
||||
mLoggedInFrame.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void showSignupForm() {
|
||||
mLoggingInFrame.setVisibility(View.GONE);
|
||||
mLoggedInFrame.setVisibility(View.GONE);
|
||||
mSignupForm.setVisibility(View.VISIBLE);
|
||||
}
|
||||
private void showError(String error) {
|
||||
mError.setText(error);
|
||||
|
@ -167,51 +188,73 @@ public class SignupFragment extends Fragment {
|
|||
|
||||
public interface OnSignupInteractionListener {
|
||||
void onSignupCompleted();
|
||||
void onLoginRequested();
|
||||
void onCancelSignup();
|
||||
}
|
||||
|
||||
private void onGetStartedClicked() {
|
||||
if (mListener != null) {
|
||||
mListener.onSignupCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void handleSignupCompleted() {
|
||||
mSignupInProgress = false;
|
||||
String username = mUsername.getText().toString().trim();
|
||||
String password = mPassword.getText().toString();
|
||||
mDialog.setMessage(getString(R.string.logging_in));
|
||||
mDialog.setCancelable(true);
|
||||
mDialog.setOnCancelListener(dialogInterface -> {
|
||||
nativeCancelLogin();
|
||||
cancelActivityIndicator();
|
||||
if (mListener != null) {
|
||||
mListener.onLoginRequested();
|
||||
}
|
||||
getActivity().runOnUiThread(() -> {
|
||||
mActivityText.setText(R.string.logging_in);
|
||||
});
|
||||
mDialog.show();
|
||||
nativeLogin(username, password, getActivity());
|
||||
mLoginInProgress = true;
|
||||
boolean keepUserLoggedIn = mKeepMeLoggedInCheckbox.isChecked();
|
||||
login(username, password, keepUserLoggedIn);
|
||||
}
|
||||
|
||||
public void handleSignupFailed(String error) {
|
||||
mSignupInProgress = false;
|
||||
getActivity().runOnUiThread(() -> {
|
||||
mSignupButton.setEnabled(true);
|
||||
cancelActivityIndicator();
|
||||
showSignupForm();
|
||||
mError.setText(error);
|
||||
mError.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
public void handleLoginCompleted(boolean success) {
|
||||
mLoginInProgress = false;
|
||||
getActivity().runOnUiThread(() -> {
|
||||
mSignupButton.setEnabled(true);
|
||||
cancelActivityIndicator();
|
||||
|
||||
if (success) {
|
||||
if (mListener != null) {
|
||||
mListener.onSignupCompleted();
|
||||
}
|
||||
mSignupSuccess = true;
|
||||
showLoggedInMessage();
|
||||
} else {
|
||||
// Registration was successful but login failed.
|
||||
// Let the user to login manually
|
||||
mListener.onLoginRequested();
|
||||
mListener.onCancelSignup();
|
||||
showSignupForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doBack() {
|
||||
if (mSignupInProgress) {
|
||||
cancelSignup();
|
||||
} else if (mLoginInProgress) {
|
||||
cancelLogin();
|
||||
}
|
||||
|
||||
|
||||
if (mSignupInProgress || mLoginInProgress) {
|
||||
showSignupForm();
|
||||
mLoginInProgress = false;
|
||||
mSignupInProgress = false;
|
||||
mSignupButton.setEnabled(true);
|
||||
return true;
|
||||
} else if (mSignupSuccess) {
|
||||
onGetStartedClicked();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package io.highfidelity.hifiinterface.fragment;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import io.highfidelity.hifiinterface.R;
|
||||
|
||||
public class StartMenuFragment extends Fragment {
|
||||
|
||||
private String TAG = "HighFidelity";
|
||||
private StartMenuInteractionListener mListener;
|
||||
|
||||
public StartMenuFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static StartMenuFragment newInstance() {
|
||||
StartMenuFragment fragment = new StartMenuFragment();
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
View rootView = inflater.inflate(R.layout.fragment_login_menu, container, false);
|
||||
rootView.findViewById(R.id.signupButton).setOnClickListener(view -> {
|
||||
if (mListener != null) {
|
||||
mListener.onSignupButtonClicked();
|
||||
}
|
||||
});
|
||||
|
||||
rootView.findViewById(R.id.loginButton).setOnClickListener(view -> {
|
||||
if (mListener != null) {
|
||||
mListener.onLoginButtonClicked();
|
||||
}
|
||||
});
|
||||
|
||||
rootView.findViewById(R.id.steamLoginButton).setOnClickListener(view -> {
|
||||
if (mListener != null) {
|
||||
mListener.onSteamLoginButtonClicked();
|
||||
}
|
||||
});
|
||||
|
||||
rootView.findViewById(R.id.takeMeInWorld).setOnClickListener(view -> {
|
||||
if (mListener != null) {
|
||||
mListener.onSkipLoginClicked();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof StartMenuInteractionListener) {
|
||||
mListener = (StartMenuInteractionListener) context;
|
||||
} else {
|
||||
throw new RuntimeException(context.toString()
|
||||
+ " must implement StartMenuInteractionListener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface must be implemented by activities that contain this
|
||||
* fragment to allow an interaction in this fragment to be communicated
|
||||
* to the activity and potentially other fragments contained in that
|
||||
* activity.
|
||||
* <p>
|
||||
* See the Android Training lesson <a href=
|
||||
* "http://developer.android.com/training/basics/fragments/communicating.html"
|
||||
* >Communicating with Other Fragments</a> for more information.
|
||||
*/
|
||||
public interface StartMenuInteractionListener {
|
||||
void onSignupButtonClicked();
|
||||
void onLoginButtonClicked();
|
||||
void onSkipLoginClicked();
|
||||
void onSteamLoginButtonClicked();
|
||||
}
|
||||
}
|
|
@ -4,9 +4,11 @@ import android.app.Fragment;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslError;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -14,6 +16,7 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.SslErrorHandler;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebResourceError;
|
||||
|
@ -25,6 +28,7 @@ import android.webkit.WebViewClient;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import io.highfidelity.hifiinterface.BuildConfig;
|
||||
import io.highfidelity.hifiinterface.R;
|
||||
import io.highfidelity.hifiinterface.WebViewActivity;
|
||||
|
||||
|
@ -32,6 +36,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
|
|||
|
||||
public static final String URL = "url";
|
||||
public static final String TOOLBAR_VISIBLE = "toolbar_visible";
|
||||
public static final String CLEAR_COOKIES = "clear_cookies";
|
||||
private static final long DELAY_HIDE_TOOLBAR_MILLIS = 3000;
|
||||
private static final long FADE_OUT_DURATION = 2000;
|
||||
|
||||
|
@ -41,6 +46,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
|
|||
private ProgressBar mProgressBar;
|
||||
private String mUrl;
|
||||
private boolean mToolbarVisible;
|
||||
private boolean mClearCookies;
|
||||
|
||||
private OnWebViewInteractionListener mListener;
|
||||
private Runnable mCloseAction;
|
||||
|
@ -170,6 +176,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
|
|||
if (getArguments() != null) {
|
||||
mUrl = getArguments().getString(URL);
|
||||
mToolbarVisible = getArguments().getBoolean(TOOLBAR_VISIBLE);
|
||||
mClearCookies = getArguments().getBoolean(CLEAR_COOKIES);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,6 +186,10 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
|
|||
View rootView = inflater.inflate(R.layout.fragment_web_view, container, false);
|
||||
mProgressBar = rootView.findViewById(R.id.toolbarProgressBar);
|
||||
myWebView = rootView.findViewById(R.id.web_view);
|
||||
if (mClearCookies) {
|
||||
CookieManager.getInstance().removeAllCookies(null);
|
||||
}
|
||||
|
||||
mHandler = new Handler();
|
||||
gestureDetector = new GestureDetector(this);
|
||||
gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
|
||||
|
@ -251,6 +262,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
|
|||
void onWebLoaded(String url, SafenessLevel safenessLevel);
|
||||
void onTitleReceived(String title);
|
||||
void onExpand();
|
||||
void onOAuthAuthorizeCallback(Uri uri);
|
||||
}
|
||||
|
||||
|
||||
|
@ -320,6 +332,18 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
|
|||
super.onLoadResource(view, url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||
if (!TextUtils.isEmpty(BuildConfig.OAUTH_REDIRECT_URI) &&
|
||||
request.getUrl().toString().startsWith(BuildConfig.OAUTH_REDIRECT_URI)) {
|
||||
if (mListener != null) {
|
||||
mListener.onOAuthAuthorizeCallback(request.getUrl());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.shouldOverrideUrlLoading(view, request);
|
||||
}
|
||||
}
|
||||
|
||||
class HiFiWebChromeClient extends WebChromeClient {
|
||||
|
|
BIN
android/app/src/main/res/drawable/encourage_login_background.jpg
Normal file
After Width: | Height: | Size: 48 KiB |
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="350dp"
|
||||
android:width="340dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="350"
|
||||
android:viewportHeight="100">
|
||||
|
|
11
android/app/src/main/res/drawable/ic_right_arrow.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="11dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="11"
|
||||
android:viewportHeight="14">
|
||||
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M2.98427,0.868092 C2.35913,0.324495,1.41169,0.390596,0.868092,1.01573 C0.324495,1.64087,0.390596,2.58831,1.01573,3.13191 L2.98427,0.868092 Z M8,7.21739 L8.93497,8.39035 L10.3436,7.26752 L8.98427,6.08548 L8,7.21739 Z M1.06503,10.827 C0.417224,11.3434,0.310672,12.2872,0.82704,12.935 C1.34341,13.5828,2.28716,13.6893,2.93497,13.173 L1.06503,10.827 Z M1.01573,3.13191 L7.01573,8.3493 L8.98427,6.08548 L2.98427,0.868092 L1.01573,3.13191 Z M7.06503,6.04443 L1.06503,10.827 L2.93497,13.173 L8.93497,8.39035 L7.06503,6.04443 Z" />
|
||||
</vector>
|
11
android/app/src/main/res/drawable/ic_steam.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="21dp"
|
||||
android:height="21dp"
|
||||
android:viewportWidth="21"
|
||||
android:viewportHeight="21">
|
||||
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M10.4866,0 C4.92045,0,0.367395,4.32104,0,9.78734 L5.45262,11.9841 C5.93184,11.651,6.51333,11.4545,7.14145,11.4545 C7.27641,11.4545,7.4083,11.4666,7.53829,11.4841 L10.1047,7.72495 C10.1083,5.56672,11.861,3.81818,14.0229,3.81818 C16.1872,3.81818,17.9416,5.57035,17.9416,7.73182 C17.9416,9.89329,16.1872,11.6455,14.0229,11.6455 C14.021,11.6455,14.0189,11.6453,14.017,11.6453 L10.0936,14.2008 C10.0986,14.2712,10.1043,14.3419,10.1043,14.4136 C10.1043,16.048,8.77791,17.3727,7.14145,17.3727 C5.69539,17.3727,4.49304,16.3376,4.2325,14.969 L0.378099,13.3841 C1.6334,17.7801,5.6822,21,10.4866,21 C16.2931,21,21,16.2991,21,10.5 C21,4.70114,16.2931,0,10.4866,0 Z M7.14145,16.0364 C6.96655,16.0364,6.79833,16.0081,6.64044,15.9569 L6.63968,15.9589 L6.59151,15.939 C6.54506,15.9224,6.49975,15.9037,6.45541,15.8831 L5.15462,15.3483 C5.50614,16.0927,6.26253,16.6091,7.14145,16.6091 C8.35546,16.6091,9.33971,15.6263,9.33971,14.4136 C9.33971,13.201,8.35546,12.2182,7.14145,12.2182 C6.87269,12.2182,6.61636,12.2688,6.37818,12.357 L7.75448,12.9114 C7.76404,12.9154,7.77359,12.9188,7.78296,12.923 L7.89001,12.9662 L7.88714,12.9732 C8.40898,13.243,8.76625,13.7861,8.76625,14.4136 C8.76625,15.3098,8.03872,16.0364,7.14145,16.0364 Z M16.7946,7.73182 C16.7946,6.20302,15.5537,4.96364,14.0229,4.96364 C12.4922,4.96364,11.2512,6.20302,11.2512,7.73182 C11.2512,9.26062,12.4922,10.5,14.0229,10.5 C15.5537,10.5,16.7946,9.26062,16.7946,7.73182 Z M12.0158,7.73182 C12.0158,6.62474,12.9144,5.72727,14.0229,5.72727 C15.1314,5.72727,16.03,6.62474,16.03,7.73182 C16.03,8.8389,15.1314,9.73636,14.0229,9.73636 C12.9144,9.73636,12.0158,8.8389,12.0158,7.73182 Z" />
|
||||
</vector>
|
24
android/app/src/main/res/drawable/rounded_button_color3.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item android:state_pressed="true" >
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="4dip" />
|
||||
<stroke android:width="1dip" android:color="@color/colorButton2" />
|
||||
<solid android:color="@color/colorButton2"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_focused="true">
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="4dip" />
|
||||
<stroke android:width="1dip" android:color="@color/colorButton2" />
|
||||
<solid android:color="@color/colorButton2"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="4dip" />
|
||||
<stroke android:width="1dip" android:color="@color/colorButton2" />
|
||||
<solid android:color="@color/colorButton2"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
24
android/app/src/main/res/drawable/rounded_button_color4.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item android:state_pressed="true" >
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="4dip" />
|
||||
<stroke android:width="1dip" android:color="@color/colorButton4" />
|
||||
<solid android:color="@color/colorButton4"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_focused="true">
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="4dip" />
|
||||
<stroke android:width="1dip" android:color="@color/colorButton4" />
|
||||
<solid android:color="@color/colorButton4"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="4dip" />
|
||||
<stroke android:width="1dip" android:color="@color/colorButton4" />
|
||||
<solid android:color="@color/colorButton4"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" android:padding="9dp">
|
||||
<corners android:radius="4dip" />
|
||||
<stroke android:width="1dip" android:color="@android:color/black" />
|
||||
<solid android:color="@color/backgroundEditText"/>
|
||||
</shape>
|
14
android/app/src/main/res/layout/activity_encourage_login.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".LoginMenuActivity">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -6,6 +6,17 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/backgroundLight">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/encourage_login_background"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#B2000000" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/header"
|
||||
android:layout_width="@dimen/header_hifi_width"
|
||||
|
@ -17,126 +28,246 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/hifi_header" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:layout_marginRight="9dp"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:textColor="@color/colorLoginError"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/username"
|
||||
app:layout_constraintLeft_toLeftOf="@id/username"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginLeft="46dp"
|
||||
android:layout_marginRight="46dp"
|
||||
android:background="@drawable/rounded_edit"
|
||||
android:padding="7dp"
|
||||
android:paddingRight="12dp"
|
||||
android:paddingTop="14dp"
|
||||
android:ems="10"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:textSize="17sp"
|
||||
android:inputType="textEmailAddress"
|
||||
android:textStyle="italic"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
android:layout_marginTop="70dp"
|
||||
android:hint="@string/username_or_email" />
|
||||
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/passwordLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="46dp"
|
||||
android:layout_marginRight="46dp"
|
||||
app:passwordToggleTint="@color/showPasswordColor"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:hintAnimationEnabled="false"
|
||||
app:passwordToggleDrawable="@drawable/selector_show_password"
|
||||
app:hintEnabled="false"
|
||||
app:layout_constraintTop_toBottomOf="@id/username"
|
||||
android:layout_marginTop="13dp"
|
||||
>
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:background="@drawable/rounded_edit"
|
||||
android:padding="7dp"
|
||||
android:drawablePadding="55dp"
|
||||
android:paddingTop="14dp"
|
||||
android:drawableEnd="@drawable/ic_eye_noshow"
|
||||
android:ems="10"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="italic"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
android:imeOptions="actionDone"
|
||||
android:hint="@string/password"
|
||||
android:inputType="textPassword" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/loginButton"
|
||||
android:layout_width="154dp"
|
||||
android:layout_height="38dp"
|
||||
android:background="@drawable/rounded_button"
|
||||
android:fontFamily="@font/raleway_semibold"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:text="@string/login"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintRight_toRightOf="@id/username"
|
||||
app:layout_constraintTop_toBottomOf="@id/forgotPassword"
|
||||
app:layout_goneMarginTop="4dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forgotPassword"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="9dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:fontFamily="@font/raleway_semibold"
|
||||
android:textSize="14dp"
|
||||
android:text="@string/forgot_password"
|
||||
android:textStyle="italic"
|
||||
app:layout_constraintRight_toRightOf="@id/passwordLayout"
|
||||
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
|
||||
android:textColor="@color/colorButton1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/signupButton"
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/loggingInFrame"
|
||||
android:layout_width="0dp"
|
||||
app:layout_constraintWidth_default="spread"
|
||||
android:layout_height="38dp"
|
||||
android:background="@drawable/rounded_secondary_button"
|
||||
android:fontFamily="@font/raleway_semibold"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:text="@string/signup"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
|
||||
app:layout_constraintTop_toTopOf="@id/loginButton"
|
||||
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
||||
app:layout_goneMarginTop="4dp"/>
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/login_form_margin_top"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/loggingInText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/logging_in"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginTop="83dp"
|
||||
/>
|
||||
<ProgressBar
|
||||
android:layout_width="101dp"
|
||||
android:layout_height="101dp"
|
||||
android:layout_marginTop="20dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/loggingInText"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:indeterminateTint="#00B4EF"
|
||||
/>
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/loggedInFrame"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/login_form_margin_top"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/loggedInText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/logged_in_welcome"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginTop="115dp"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/getStarted"
|
||||
android:layout_width="@dimen/button_medium_width"
|
||||
android:layout_height="@dimen/button_medium_height"
|
||||
android:layout_marginTop="22dp"
|
||||
android:background="@drawable/rounded_button_color1"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:text="@string/get_started"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="@dimen/button_medium_text_size"
|
||||
app:layout_constraintTop_toBottomOf="@id/loggedInText"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_goneMarginTop="4dp"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/loginForm"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/login_form_margin_top"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/error"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:layout_marginRight="9dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="@color/colorLoginError"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/username"
|
||||
app:layout_constraintLeft_toLeftOf="@id/username"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="27dp"
|
||||
android:layout_marginLeft="@dimen/login_margin"
|
||||
android:layout_marginRight="@dimen/login_margin"
|
||||
android:background="@color/white_opaque"
|
||||
android:paddingLeft="@dimen/edit_text_padding"
|
||||
android:ems="10"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="@dimen/login_edit_text_size"
|
||||
android:inputType="textEmailAddress"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
android:hint="@string/username_or_email"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="83dp"/>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/passwordLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/login_margin"
|
||||
android:layout_marginRight="@dimen/login_margin"
|
||||
android:background="@color/white_opaque"
|
||||
app:passwordToggleTint="@color/showPasswordColor"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:hintAnimationEnabled="false"
|
||||
app:passwordToggleDrawable="@drawable/selector_show_password"
|
||||
app:hintEnabled="false"
|
||||
app:layout_constraintTop_toBottomOf="@id/username"
|
||||
android:layout_marginTop="15dp"
|
||||
>
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/login_edit_text_height"
|
||||
android:background="@color/white_opaque"
|
||||
android:paddingLeft="@dimen/edit_text_padding"
|
||||
android:drawablePadding="45dp"
|
||||
android:drawableEnd="@drawable/ic_eye_noshow"
|
||||
android:ems="10"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="@dimen/login_edit_text_size"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
android:imeOptions="actionDone"
|
||||
android:hint="@string/password"
|
||||
android:inputType="textPassword" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/keepMeLoggedIn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13dp"
|
||||
android:layout_marginRight="66dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:padding="0dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/keepMeLoggedInLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="12sp"
|
||||
android:text="@string/keep_me_logged_in"
|
||||
app:layout_constraintRight_toLeftOf="@id/keepMeLoggedIn"
|
||||
app:layout_constraintTop_toTopOf="@id/keepMeLoggedIn"
|
||||
app:layout_constraintBottom_toBottomOf="@id/keepMeLoggedIn"
|
||||
android:textColor="@color/white_opaque"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/loginButton"
|
||||
android:layout_width="@dimen/button_medium_width"
|
||||
android:layout_height="@dimen/button_medium_height"
|
||||
android:background="@drawable/rounded_button_color3"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:layout_marginTop="@dimen/button_medium_margin"
|
||||
android:text="@string/log_in"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="@dimen/button_medium_text_size"
|
||||
app:layout_constraintRight_toRightOf="@id/username"
|
||||
app:layout_constraintTop_toBottomOf="@id/keepMeLoggedIn" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
|
||||
app:layout_constraintTop_toTopOf="@id/loginButton"
|
||||
app:layout_constraintBottom_toBottomOf="@id/loginButton"
|
||||
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="@dimen/button_medium_text_size"
|
||||
android:text="@string/cancel_uppercase" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forgotPassword"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="18dp"
|
||||
android:text="@string/cant_access_your_account"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/loginButton"
|
||||
android:textColor="@color/colorButton1"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/takeMeInWorld"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:padding="5dp"
|
||||
android:text="@string/take_me_in_world"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:textColor="@color/white_opaque"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_right_arrow"
|
||||
android:layout_marginLeft="4dp"
|
||||
app:layout_constraintLeft_toRightOf="@id/takeMeInWorld"
|
||||
app:layout_constraintTop_toTopOf="@id/takeMeInWorld"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takeMeInWorld"
|
||||
/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
122
android/app/src/main/res/layout/fragment_login_menu.xml
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".fragment.StartMenuFragment">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/encourage_login_background"
|
||||
android:scaleType="fitXY"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/header"
|
||||
android:layout_width="@dimen/header_hifi_width"
|
||||
android:layout_height="@dimen/header_hifi_height"
|
||||
android:layout_marginTop="@dimen/header_hifi_margin_top"
|
||||
android:contentDescription="HighFidelity"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/hifi_header" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="@dimen/login_menu_text_size"
|
||||
android:layout_marginTop="37dp"
|
||||
android:text="@string/be_anywere"
|
||||
android:gravity="center"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/signupButton"
|
||||
android:layout_width="@dimen/button_large_width"
|
||||
android:layout_height="@dimen/button_large_height"
|
||||
android:layout_marginTop="48dp"
|
||||
android:background="@drawable/rounded_button_color1"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:text="@string/signup_uppercase"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="@dimen/button_large_text_size"
|
||||
app:layout_constraintTop_toBottomOf="@id/text"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/login_menu_translucent_rectangle_height"
|
||||
app:layout_constraintBottom_toBottomOf="parent" android:background="#B2000000">
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/loginButton"
|
||||
android:layout_width="@dimen/button_large_width"
|
||||
android:layout_height="@dimen/button_large_height"
|
||||
android:background="@drawable/rounded_button_color3"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:layout_marginTop="@dimen/login_menu_button_margin_top"
|
||||
android:text="@string/log_in"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="@dimen/button_large_text_size"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/steamLoginButton"
|
||||
android:layout_width="@dimen/button_large_width"
|
||||
android:layout_height="@dimen/button_large_height"
|
||||
android:background="@drawable/rounded_button_color4"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/steam_log_in"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="@dimen/button_large_text_size"
|
||||
android:drawableLeft="@drawable/ic_steam"
|
||||
android:paddingLeft="38dp"
|
||||
android:paddingRight="38dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/loginButton"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/takeMeInWorld"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:padding="5dp"
|
||||
android:text="@string/take_me_in_world"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:textColor="@color/white_opaque"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_right_arrow"
|
||||
android:layout_marginLeft="4dp"
|
||||
app:layout_constraintLeft_toRightOf="@id/takeMeInWorld"
|
||||
app:layout_constraintTop_toTopOf="@id/takeMeInWorld"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takeMeInWorld"
|
||||
/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -1,63 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/backgroundLight">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/header"
|
||||
android:layout_width="@dimen/header_hifi_width"
|
||||
android:layout_height="@dimen/header_hifi_height"
|
||||
android:layout_marginTop="@dimen/header_hifi_margin_top"
|
||||
android:contentDescription="HighFidelity"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/hifi_header" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcome"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="50dp"
|
||||
android:paddingLeft="86dp"
|
||||
android:paddingRight="86dp"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:textColor="@color/clearText"
|
||||
android:textSize="24sp"
|
||||
android:text="@string/signedin_welcome"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:gravity="center"
|
||||
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/getStarted"
|
||||
android:layout_width="217dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:background="@drawable/rounded_button"
|
||||
android:fontFamily="@font/raleway_semibold"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingLeft="25dp"
|
||||
android:paddingRight="25dp"
|
||||
android:paddingTop="0dp"
|
||||
android:text="@string/get_started"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/welcome"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
|
||||
app:layout_goneMarginTop="4dp"/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -6,6 +6,18 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/backgroundLight">
|
||||
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/encourage_login_background"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#B2000000" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/header"
|
||||
android:layout_width="@dimen/header_hifi_width"
|
||||
|
@ -17,93 +29,168 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/hifi_header" />
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/loggingInFrame"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="100dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/activityText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/logging_in"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginTop="83dp"
|
||||
/>
|
||||
<ProgressBar
|
||||
android:layout_width="101dp"
|
||||
android:layout_height="101dp"
|
||||
android:layout_marginTop="20dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/activityText"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:indeterminateTint="#00B4EF"
|
||||
/>
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/loggedInFrame"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="100dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/loggedInText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/logged_in_welcome"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginTop="115dp"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/getStarted"
|
||||
android:layout_width="@dimen/button_medium_width"
|
||||
android:layout_height="@dimen/button_medium_height"
|
||||
android:layout_marginTop="22dp"
|
||||
android:background="@drawable/rounded_button_color1"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:text="@string/get_started"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="@dimen/button_medium_text_size"
|
||||
app:layout_constraintTop_toBottomOf="@id/loggedInText"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/signupForm"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="100dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:layout_marginRight="9dp"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="@color/colorLoginError"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/email"
|
||||
app:layout_constraintLeft_toLeftOf="@id/email"
|
||||
app:layout_constraintRight_toRightOf="@id/email"
|
||||
app:layout_constraintBottom_toTopOf="@id/username"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="@id/username"
|
||||
app:layout_constraintRight_toRightOf="@id/username"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/email"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginLeft="46dp"
|
||||
android:layout_marginRight="46dp"
|
||||
android:background="@drawable/rounded_edit"
|
||||
android:padding="7dp"
|
||||
android:paddingRight="12dp"
|
||||
android:paddingTop="14dp"
|
||||
android:ems="10"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:textSize="17sp"
|
||||
android:inputType="textEmailAddress"
|
||||
android:textStyle="italic"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
android:layout_marginTop="70dp"
|
||||
android:hint="@string/email" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginLeft="46dp"
|
||||
android:layout_marginRight="46dp"
|
||||
android:background="@drawable/rounded_edit"
|
||||
android:padding="7dp"
|
||||
android:paddingRight="12dp"
|
||||
android:paddingTop="14dp"
|
||||
android:layout_height="@dimen/login_edit_text_height"
|
||||
android:layout_marginLeft="@dimen/signup_margin"
|
||||
android:layout_marginRight="@dimen/signup_margin"
|
||||
android:background="@color/white_opaque"
|
||||
android:paddingLeft="@dimen/edit_text_padding"
|
||||
android:ems="10"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:textSize="17sp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="@dimen/login_edit_text_size"
|
||||
android:inputType="text"
|
||||
android:textStyle="italic"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
app:layout_constraintTop_toBottomOf="@id/email"
|
||||
android:layout_marginTop="7dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="70dp"
|
||||
android:hint="@string/username" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/email"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/login_edit_text_height"
|
||||
android:layout_marginLeft="@dimen/signup_margin"
|
||||
android:layout_marginRight="@dimen/signup_margin"
|
||||
android:background="@color/white_opaque"
|
||||
android:paddingLeft="@dimen/edit_text_padding"
|
||||
android:ems="10"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="@dimen/login_edit_text_size"
|
||||
android:inputType="textEmailAddress"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
app:layout_constraintTop_toBottomOf="@id/username"
|
||||
android:layout_marginTop="14dp"
|
||||
android:hint="@string/email" />
|
||||
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/passwordLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="46dp"
|
||||
android:layout_marginRight="46dp"
|
||||
android:layout_marginLeft="@dimen/signup_margin"
|
||||
android:layout_marginRight="@dimen/signup_margin"
|
||||
app:passwordToggleTint="@color/showPasswordColor"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:hintAnimationEnabled="false"
|
||||
app:passwordToggleDrawable="@drawable/selector_show_password"
|
||||
app:hintEnabled="false"
|
||||
app:layout_constraintTop_toBottomOf="@id/username"
|
||||
android:layout_marginTop="7dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/email"
|
||||
android:layout_marginTop="15dp"
|
||||
>
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:background="@drawable/rounded_edit"
|
||||
android:padding="7dp"
|
||||
android:layout_height="27dp"
|
||||
android:background="@color/white_opaque"
|
||||
android:paddingLeft="@dimen/edit_text_padding"
|
||||
android:drawablePadding="55dp"
|
||||
android:paddingTop="14dp"
|
||||
android:drawableEnd="@drawable/ic_eye_noshow"
|
||||
android:ems="10"
|
||||
android:fontFamily="@font/raleway"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="italic"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="@dimen/login_edit_text_size"
|
||||
android:textColor="@color/editTextColor"
|
||||
android:textColorHint="@color/editTextColor"
|
||||
android:gravity="left|center_vertical"
|
||||
|
@ -112,40 +199,54 @@
|
|||
android:inputType="textPassword" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/keepMeLoggedIn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13dp"
|
||||
android:layout_marginRight="66dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:padding="0dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/keepMeLoggedInLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="12sp"
|
||||
android:text="@string/keep_me_logged_in"
|
||||
app:layout_constraintRight_toLeftOf="@id/keepMeLoggedIn"
|
||||
app:layout_constraintTop_toTopOf="@id/keepMeLoggedIn"
|
||||
app:layout_constraintBottom_toBottomOf="@id/keepMeLoggedIn"
|
||||
android:textColor="@color/white_opaque"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/signupButton"
|
||||
android:layout_width="154dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_marginTop="44dp"
|
||||
android:background="@drawable/rounded_button"
|
||||
android:fontFamily="@font/raleway_semibold"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:text="@string/signup"
|
||||
android:layout_width="@dimen/button_medium_width"
|
||||
android:layout_height="@dimen/button_medium_height"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/rounded_button_color1"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:text="@string/signup_uppercase"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="18sp"
|
||||
android:textSize="@dimen/button_medium_text_size"
|
||||
app:layout_constraintRight_toRightOf="@id/username"
|
||||
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
|
||||
app:layout_goneMarginTop="4dp"/>
|
||||
app:layout_constraintTop_toBottomOf="@id/keepMeLoggedIn" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
app:layout_constraintWidth_default="spread"
|
||||
android:layout_height="38dp"
|
||||
android:background="@drawable/rounded_secondary_button"
|
||||
android:fontFamily="@font/raleway_semibold"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="@color/white_opaque"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="18sp"
|
||||
<TextView
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
|
||||
app:layout_constraintTop_toTopOf="@id/signupButton"
|
||||
app:layout_constraintBottom_toBottomOf="@id/signupButton"
|
||||
app:layout_constraintRight_toLeftOf="@id/signupButton"
|
||||
app:layout_goneMarginTop="4dp"/>
|
||||
android:textColor="@color/white_opaque"
|
||||
android:fontFamily="@font/raleway_bold"
|
||||
android:textSize="@dimen/button_medium_text_size"
|
||||
android:text="@string/cancel_uppercase" />
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
|
22
android/app/src/main/res/values-w385dp/dimens.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="header_hifi_margin_top">35dp</dimen>
|
||||
<dimen name="header_hifi_height">84dp</dimen>
|
||||
<dimen name="header_hifi_width">340dp</dimen>
|
||||
<dimen name="button_medium_width">171dp</dimen>
|
||||
<dimen name="button_medium_height">42dp</dimen>
|
||||
<dimen name="button_medium_margin">10dp</dimen>
|
||||
<dimen name="login_edit_text_size">14sp</dimen>
|
||||
<dimen name="button_large_text_size">18sp</dimen>
|
||||
<dimen name="button_medium_text_size">18sp</dimen>
|
||||
<dimen name="login_margin">72dp</dimen>
|
||||
<dimen name="signup_margin">76dp</dimen>
|
||||
<dimen name="login_form_margin_top">100dp</dimen>
|
||||
<dimen name="login_edit_text_height">27dp</dimen>
|
||||
<dimen name="button_large_width">238dp</dimen>
|
||||
<dimen name="button_large_height">42dp</dimen>
|
||||
<dimen name="login_menu_translucent_rectangle_height">270dp</dimen>
|
||||
<dimen name="login_menu_button_margin_top">86dp</dimen>
|
||||
<dimen name="login_menu_text_size">22sp</dimen>
|
||||
<dimen name="login_edit_text_padding">16dp</dimen>
|
||||
</resources>
|
|
@ -10,6 +10,8 @@
|
|||
<color name="tabs">#1EB5EC</color>
|
||||
<color name="colorButton1">#00B4EF</color>
|
||||
<color name="colorButton2">#828282</color>
|
||||
<color name="colorButton3">#8F8F8F</color>
|
||||
<color name="colorButton4">#434343</color>
|
||||
<color name="backgroundDark">#333333</color>
|
||||
<color name="backgroundLight">#4F4F4F</color>
|
||||
<color name="backgroundSearch">#33999999</color>
|
||||
|
|
|
@ -33,10 +33,26 @@
|
|||
<dimen name="domainMarginBottom">6dp</dimen>
|
||||
<dimen name="domainNameHeight">64dp</dimen>
|
||||
|
||||
<dimen name="header_hifi_margin_top">56dp</dimen>
|
||||
<dimen name="header_hifi_height">101dp</dimen>
|
||||
<dimen name="header_hifi_width">425dp</dimen>
|
||||
<dimen name="header_hifi_margin_top">32dp</dimen>
|
||||
<dimen name="header_hifi_height">76dp</dimen>
|
||||
<dimen name="header_hifi_width">306dp</dimen>
|
||||
|
||||
<dimen name="list_vertical_padding">8dp</dimen>
|
||||
<dimen name="button_medium_width">150dp</dimen>
|
||||
<dimen name="button_medium_height">38dp</dimen>
|
||||
<dimen name="login_margin">65dp</dimen>
|
||||
<dimen name="signup_margin">68dp</dimen>
|
||||
<dimen name="login_form_margin_top">90dp</dimen>
|
||||
<dimen name="button_medium_margin">9dp</dimen>
|
||||
<dimen name="button_medium_text_size">16sp</dimen>
|
||||
<dimen name="button_large_text_size">16sp</dimen>
|
||||
<dimen name="login_edit_text_size">13sp</dimen>
|
||||
<dimen name="login_edit_text_height">24dp</dimen>
|
||||
<dimen name="button_large_width">214dp</dimen>
|
||||
<dimen name="button_large_height">38dp</dimen>
|
||||
<dimen name="login_menu_translucent_rectangle_height">300dp</dimen>
|
||||
<dimen name="login_menu_button_margin_top">77dp</dimen>
|
||||
<dimen name="login_menu_text_size">20sp</dimen>
|
||||
<dimen name="login_edit_text_padding">14dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
<string name="password">Password</string>
|
||||
<string name="login">Login</string>
|
||||
<string name="logout">Logout</string>
|
||||
<string name="forgot_password"><u>Forgot password?</u>\u00A0</string>
|
||||
<string name="cant_access_your_account"><u>Can\u0027t access your account?</u></string>
|
||||
<string name="login_username_or_password_incorrect">Username or password incorrect.</string>
|
||||
<string name="logging_in">Logging into High Fidelity</string>
|
||||
<string name="logging_in">Logging in</string>
|
||||
<string name="search_hint"><i>Search for a place by name</i>\u00A0</string>
|
||||
<string name="search_loading">Loading places…</string>
|
||||
<string name="search_no_results">No places exist with that name</string>
|
||||
|
@ -26,16 +26,20 @@
|
|||
<string name="your_last_location">Your Last Location</string>
|
||||
<string name="online">Online</string>
|
||||
<string name="signup">Sign Up</string>
|
||||
<string name="signup_uppercase">SIGN UP</string>
|
||||
<string name="creating_account">Creating your High Fidelity account</string>
|
||||
<string name="signup_email_username_or_password_incorrect">Email, username or password incorrect.</string>
|
||||
<string name="signedin_welcome">You are now signed into High Fidelity</string>
|
||||
<string name="logged_in_welcome">You are now logged in!</string>
|
||||
<string name="welcome">Welcome</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="get_started">Get Started</string>
|
||||
<string name="cancel_uppercase">CANCEL</string>
|
||||
<string name="get_started">GET STARTED</string>
|
||||
|
||||
<!-- tags -->
|
||||
<string name="tagFragmentHome">tagFragmentHome</string>
|
||||
<string name="tagFragmentLogin">tagFragmentLogin</string>
|
||||
<string name="tagFragmentLoggingIn">tagFragmentLogginIn</string>
|
||||
<string name="tagFragmentSignup">tagFragmentSignup</string>
|
||||
<string name="tagFragmentPolicy">tagFragmentPolicy</string>
|
||||
<string name="tagFragmentPeople">tagFragmentPeople</string>
|
||||
|
@ -45,4 +49,9 @@
|
|||
<string name="AEC">AEC</string>
|
||||
<string name="acoustic_echo_cancellation">Acoustic Echo Cancellation</string>
|
||||
<string name="settings_developer">Developer</string>
|
||||
<string name="log_in">LOG IN</string>
|
||||
<string name="keep_me_logged_in">Keep Me Logged In</string>
|
||||
<string name="take_me_in_world">No thanks, take me in-world!</string>
|
||||
<string name="be_anywere">BE ANYWHERE, WITH ANYONE \nRIGHT NOW</string>
|
||||
<string name="steam_log_in">STEAM LOG IN</string>
|
||||
</resources>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<SwitchPreference
|
||||
android:key="aec"
|
||||
android:title="@string/AEC"
|
||||
android:summary="@string/acoustic_echo_cancellation" />
|
||||
android:summary="@string/acoustic_echo_cancellation"
|
||||
android:defaultValue="true" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
|
@ -11,7 +11,7 @@ setup_memory_debugger()
|
|||
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(
|
||||
audio avatars octree gpu graphics fbx entities
|
||||
audio avatars octree gpu graphics fbx hfm entities
|
||||
networking animation recording shared script-engine embedded-webserver
|
||||
controllers physics plugins midi image
|
||||
)
|
||||
|
|
|
@ -206,7 +206,7 @@ endif()
|
|||
link_hifi_libraries(
|
||||
shared workload task octree ktx gpu gl procedural graphics graphics-scripting render
|
||||
pointers
|
||||
recording fbx networking model-networking entities avatars trackers
|
||||
recording hfm fbx networking model-networking entities avatars trackers
|
||||
audio audio-client animation script-engine physics
|
||||
render-utils entities-renderer avatars-renderer ui qml auto-updater midi
|
||||
controllers plugins image trackers
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
window.isKeyboardRaised = false;
|
||||
window.isNumericKeyboard = false;
|
||||
window.isPasswordField = false;
|
||||
window.lastActiveElement = null;
|
||||
|
||||
function getActiveElement() {
|
||||
return document.activeElement;
|
||||
}
|
||||
|
||||
function shouldSetPasswordField() {
|
||||
var nodeType = document.activeElement.type;
|
||||
|
@ -65,10 +70,11 @@
|
|||
var keyboardRaised = shouldRaiseKeyboard();
|
||||
var numericKeyboard = shouldSetNumeric();
|
||||
var passwordField = shouldSetPasswordField();
|
||||
var activeElement = getActiveElement();
|
||||
|
||||
if (isWindowFocused &&
|
||||
(keyboardRaised !== window.isKeyboardRaised || numericKeyboard !== window.isNumericKeyboard
|
||||
|| passwordField !== window.isPasswordField)) {
|
||||
|| passwordField !== window.isPasswordField || activeElement !== window.lastActiveElement)) {
|
||||
|
||||
if (typeof EventBridge !== "undefined" && EventBridge !== null) {
|
||||
EventBridge.emitWebEvent(
|
||||
|
@ -90,6 +96,7 @@
|
|||
window.isKeyboardRaised = keyboardRaised;
|
||||
window.isNumericKeyboard = numericKeyboard;
|
||||
window.isPasswordField = passwordField;
|
||||
window.lastActiveElement = activeElement;
|
||||
}
|
||||
}, POLL_FREQUENCY);
|
||||
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
<svg width="22" height="26" fill="none" version="1.1" viewBox="0 0 22 26" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="#000" stroke-linejoin="round" stroke-width="2"/>
|
||||
<circle class="st1" cx="19.407" cy="2.5881" r="2.5846" fill="#ef3b4e" stroke-width=".24043"/>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#EF3B4E;}
|
||||
</style>
|
||||
<g>
|
||||
<circle cx="27.8" cy="13.3" r="2.4"/>
|
||||
<circle cx="19.7" cy="7.2" r="2.3"/>
|
||||
<circle cx="9.4" cy="6.9" r="2.2"/>
|
||||
<path d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8c-0.4-0.7-0.7-1.6-0.7-2.5
|
||||
c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2c0.3,0.2,0.6,0.2,0.9,0.2
|
||||
s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29v12.8l-12.5-7.2V21.7z
|
||||
M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
|
||||
<circle cx="25" cy="20.3" r="2.8"/>
|
||||
<circle cx="20" cy="14.6" r="2.4"/>
|
||||
</g>
|
||||
<circle class="st0" cx="44.1" cy="6" r="5.6"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 1 KiB |
|
@ -1,3 +1,16 @@
|
|||
<svg width="22" height="26" viewBox="0 0 22 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="black" stroke-width="2" stroke-linejoin="round"/>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<g>
|
||||
<circle cx="27.8" cy="13.3" r="2.4"/>
|
||||
<circle cx="19.7" cy="7.2" r="2.3"/>
|
||||
<circle cx="9.4" cy="6.9" r="2.2"/>
|
||||
<path d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8c-0.4-0.7-0.7-1.6-0.7-2.5
|
||||
c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2c0.3,0.2,0.6,0.2,0.9,0.2
|
||||
s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29v12.8l-12.5-7.2V21.7z
|
||||
M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
|
||||
<circle cx="25" cy="20.3" r="2.8"/>
|
||||
<circle cx="20" cy="14.6" r="2.4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 966 B |
|
@ -1,4 +1,21 @@
|
|||
<svg width="22" height="26" fill="none" version="1.1" viewBox="0 0 22 26" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="#fff" stroke-linejoin="round" stroke-width="2"/>
|
||||
<circle class="st1" cx="19.41" cy="2.5828" r="2.5846" fill="#ef3b4e" stroke-width=".24043"/>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#EF3B4E;}
|
||||
</style>
|
||||
<g>
|
||||
<circle class="st0" cx="27.8" cy="13.3" r="2.4"/>
|
||||
<circle class="st0" cx="19.7" cy="7.2" r="2.3"/>
|
||||
<circle class="st0" cx="9.4" cy="6.9" r="2.2"/>
|
||||
<path class="st0" d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8
|
||||
c-0.4-0.7-0.7-1.6-0.7-2.5c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2
|
||||
c0.3,0.2,0.6,0.2,0.9,0.2s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29
|
||||
v12.8l-12.5-7.2V21.7z M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
|
||||
<circle class="st0" cx="25" cy="20.3" r="2.8"/>
|
||||
<circle class="st0" cx="20" cy="14.6" r="2.4"/>
|
||||
</g>
|
||||
<circle class="st1" cx="44.1" cy="6" r="5.6"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 1.1 KiB |
|
@ -1,3 +1,19 @@
|
|||
<svg width="22" height="26" viewBox="0 0 22 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="white" stroke-width="2" stroke-linejoin="round"/>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<circle class="st0" cx="27.8" cy="13.3" r="2.4"/>
|
||||
<circle class="st0" cx="19.7" cy="7.2" r="2.3"/>
|
||||
<circle class="st0" cx="9.4" cy="6.9" r="2.2"/>
|
||||
<path class="st0" d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8
|
||||
c-0.4-0.7-0.7-1.6-0.7-2.5c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2
|
||||
c0.3,0.2,0.6,0.2,0.9,0.2s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29
|
||||
v12.8l-12.5-7.2V21.7z M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
|
||||
<circle class="st0" cx="25" cy="20.3" r="2.8"/>
|
||||
<circle class="st0" cx="20" cy="14.6" r="2.4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 1.1 KiB |
|
@ -50,6 +50,9 @@ Item {
|
|||
StatText {
|
||||
text: root.positionText
|
||||
}
|
||||
StatText {
|
||||
text: root.recenterText
|
||||
}
|
||||
StatText {
|
||||
text: "Anim Vars:--------------------------------------------------------------------------------"
|
||||
}
|
||||
|
@ -92,6 +95,9 @@ Item {
|
|||
StatText {
|
||||
text: root.rotationText
|
||||
}
|
||||
StatText {
|
||||
text: root.sittingText
|
||||
}
|
||||
StatText {
|
||||
text: "State Machines:---------------------------------------------------------------------------"
|
||||
}
|
||||
|
@ -122,6 +128,9 @@ Item {
|
|||
StatText {
|
||||
text: root.velocityText
|
||||
}
|
||||
StatText {
|
||||
text: root.walkingText
|
||||
}
|
||||
StatText {
|
||||
text: "Alpha Values:--------------------------------------------------------------------------"
|
||||
}
|
||||
|
|
|
@ -114,7 +114,6 @@ ScrollingWindow {
|
|||
sourceSize: Qt.size(width, height);
|
||||
verticalAlignment: Image.AlignVCenter;
|
||||
horizontalAlignment: Image.AlignHCenter
|
||||
onSourceChanged: console.log("Icon url: " + source)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,10 +248,6 @@ ScrollingWindow {
|
|||
root.loadingChanged(loadRequest.status);
|
||||
}
|
||||
|
||||
onIconChanged: {
|
||||
console.log("New icon: " + icon)
|
||||
}
|
||||
|
||||
onWindowCloseRequested: {
|
||||
root.destroy();
|
||||
}
|
||||
|
|
|
@ -34,10 +34,34 @@ Item {
|
|||
webViewCore.stop();
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: delayedUnfocuser
|
||||
repeat: false
|
||||
interval: 200
|
||||
onTriggered: {
|
||||
|
||||
// The idea behind this is to delay unfocusing, so that fast lower/raise will not result actual unfocusing.
|
||||
// Fast lower/raise happens every time keyboard is being re-raised (see the code below in OffscreenQmlSurface::setKeyboardRaised)
|
||||
//
|
||||
// if (raised) {
|
||||
// item->setProperty("keyboardRaised", QVariant(!raised));
|
||||
// }
|
||||
//
|
||||
// item->setProperty("keyboardRaised", QVariant(raised));
|
||||
//
|
||||
|
||||
webViewCore.runJavaScript("if (document.activeElement) document.activeElement.blur();", function(result) {
|
||||
console.log('unfocus completed: ', result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function unfocus() {
|
||||
webViewCore.runJavaScript("if (document.activeElement) document.activeElement.blur();", function(result) {
|
||||
console.log('unfocus completed: ', result);
|
||||
});
|
||||
delayedUnfocuser.start();
|
||||
}
|
||||
|
||||
function stopUnfocus() {
|
||||
delayedUnfocuser.stop();
|
||||
}
|
||||
|
||||
function onLoadingChanged(loadRequest) {
|
||||
|
|
|
@ -13,6 +13,8 @@ Item {
|
|||
onKeyboardRaisedChanged: {
|
||||
if(!keyboardRaised) {
|
||||
webroot.unfocus();
|
||||
} else {
|
||||
webroot.stopUnfocus();
|
||||
}
|
||||
}
|
||||
property bool punctuationMode: false
|
||||
|
|
|
@ -17,6 +17,8 @@ Item {
|
|||
onKeyboardRaisedChanged: {
|
||||
if(!keyboardRaised) {
|
||||
webroot.unfocus();
|
||||
} else {
|
||||
webroot.stopUnfocus();
|
||||
}
|
||||
}
|
||||
property bool punctuationMode: false
|
||||
|
|
|
@ -15,6 +15,8 @@ Item {
|
|||
onKeyboardRaisedChanged: {
|
||||
if(!keyboardRaised) {
|
||||
webroot.unfocus();
|
||||
} else {
|
||||
webroot.stopUnfocus();
|
||||
}
|
||||
}
|
||||
property bool punctuationMode: false
|
||||
|
|
|
@ -80,8 +80,6 @@ ModalWindow {
|
|||
property int clickedButton: OriginalDialogs.StandardButton.NoButton;
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("Helper " + helper + " drives " + drives);
|
||||
|
||||
fileDialogItem.keyboardEnabled = HMD.active;
|
||||
|
||||
// HACK: The following lines force the model to initialize properly such that the go-up button
|
||||
|
@ -809,7 +807,6 @@ ModalWindow {
|
|||
}
|
||||
}
|
||||
|
||||
console.log("Selecting " + selection)
|
||||
selectedFile(selection);
|
||||
root.destroy();
|
||||
}
|
||||
|
|
|
@ -765,8 +765,7 @@ TabletModalWindow {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Selecting " + selection)
|
||||
|
||||
selectedFile(selection);
|
||||
root.destroy();
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ Preference {
|
|||
|
||||
Component.onCompleted: {
|
||||
dataTextField.text = preference.value;
|
||||
console.log("MyAvatar modelName " + MyAvatar.getFullAvatarModelName())
|
||||
console.log("Application : " + ApplicationInterface)
|
||||
ApplicationInterface.fullAvatarURLChanged.connect(processNewAvatar);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@ Preference {
|
|||
dir: fileDialogHelper.pathToUrl(preference.value)
|
||||
});
|
||||
browser.selectedFile.connect(function(fileUrl){
|
||||
console.log(fileUrl);
|
||||
dataTextField.text = fileDialogHelper.urlToPath(fileUrl);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
catch(err) {
|
||||
console.error(err);
|
||||
//console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ Item {
|
|||
property string defaultThumbnail: Qt.resolvedUrl("../../images/default-domain.gif");
|
||||
property int shadowHeight: 10;
|
||||
property bool hovered: false
|
||||
property bool scrolling: false
|
||||
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
|
@ -133,7 +134,7 @@ Item {
|
|||
}
|
||||
onStatusChanged: {
|
||||
if (status == Image.Error) {
|
||||
console.log("source: " + source + ": failed to load " + hifiUrl);
|
||||
console.log("source: " + source + ": failed to load");
|
||||
source = defaultThumbnail;
|
||||
}
|
||||
}
|
||||
|
@ -236,11 +237,12 @@ Item {
|
|||
property var hoverThunk: function () { };
|
||||
property var unhoverThunk: function () { };
|
||||
Rectangle {
|
||||
anchors.fill: parent;
|
||||
visible: root.hovered
|
||||
color: "transparent";
|
||||
border.width: 4; border.color: hifiStyleConstants.colors.primaryHighlight;
|
||||
z: 1;
|
||||
anchors.fill: parent
|
||||
visible: root.hovered && !root.scrolling
|
||||
color: "transparent"
|
||||
border.width: 4
|
||||
border.color: hifiStyleConstants.colors.primaryHighlight
|
||||
z: 1
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
@ -255,6 +257,12 @@ Item {
|
|||
hoverThunk();
|
||||
}
|
||||
onExited: unhoverThunk();
|
||||
onCanceled: unhoverThunk();
|
||||
}
|
||||
MouseArea {
|
||||
// This second mouse area causes onEntered to fire on the first if you scroll just a little and the cursor stays on
|
||||
// the original card. I.e., the original card is re-highlighted if the cursor is on it after scrolling finishes.
|
||||
anchors.fill: parent
|
||||
}
|
||||
StateImage {
|
||||
id: actionIcon;
|
||||
|
|
|
@ -103,19 +103,14 @@ OriginalDesktop.Desktop {
|
|||
property bool autoAdd: false
|
||||
|
||||
function initWebviewProfileHandlers(profile) {
|
||||
console.log("The webview url in desktop is: " + currentUrl);
|
||||
downloadUrl = currentUrl;
|
||||
if (webViewProfileSetup) return;
|
||||
webViewProfileSetup = true;
|
||||
|
||||
profile.downloadRequested.connect(function(download){
|
||||
console.log("Download start: " + download.state);
|
||||
adaptedPath = File.convertUrlToPath(downloadUrl);
|
||||
tempDir = File.getTempDir();
|
||||
console.log("Temp dir created: " + tempDir);
|
||||
download.path = tempDir + "/" + adaptedPath;
|
||||
console.log("Path where object should download: " + download.path);
|
||||
console.log("Auto add: " + autoAdd);
|
||||
download.accept();
|
||||
if (download.state === WebEngineDownloadItem.DownloadInterrupted) {
|
||||
console.log("download failed to complete");
|
||||
|
|
|
@ -141,6 +141,8 @@ Column {
|
|||
textSizeSmall: root.textSizeSmall;
|
||||
stackShadowNarrowing: root.stackShadowNarrowing;
|
||||
shadowHeight: root.stackedCardShadowHeight;
|
||||
scrolling: scroll.moving
|
||||
|
||||
hoverThunk: function () {
|
||||
hovered = true;
|
||||
if(root.autoScrollTimerEnabled) {
|
||||
|
|
|
@ -1287,7 +1287,7 @@ Rectangle {
|
|||
connectionsOnlineDot.visible = message.shouldShowDot;
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message:', JSON.stringify(message));
|
||||
console.log('Pal.qml: Unrecognized message');
|
||||
}
|
||||
}
|
||||
function sortModel() {
|
||||
|
|
|
@ -20,7 +20,6 @@ Item {
|
|||
// Public function for initiating an http request.
|
||||
// REQUIRES parent to be root to have sendToScript!
|
||||
function request(options, callback) {
|
||||
console.debug('HttpRequest', JSON.stringify(options));
|
||||
httpCalls[httpCounter] = callback;
|
||||
var message = {method: 'http.request', params: options, id: httpCounter++, jsonrpc: "2.0"};
|
||||
parent.sendToScript(message);
|
||||
|
@ -33,7 +32,6 @@ Item {
|
|||
return;
|
||||
}
|
||||
delete httpCalls[message.id];
|
||||
console.debug('HttpRequest response', JSON.stringify(message));
|
||||
callback(message.error, message.response);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ Rectangle {
|
|||
spectatorCameraPreview.visible = message.setting;
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from spectatorCamera.js:', JSON.stringify(message));
|
||||
console.log('Unrecognized message from spectatorCamera.js');
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
|
|
|
@ -261,7 +261,6 @@ Rectangle {
|
|||
anchors.right: parent.right
|
||||
onLinkActivated: {
|
||||
popup.showSpecifyWearableUrl(function(url) {
|
||||
console.debug('popup.showSpecifyWearableUrl: ', url);
|
||||
addWearable(root.avatarName, url);
|
||||
modified = true;
|
||||
});
|
||||
|
|
|
@ -29,9 +29,6 @@ Item {
|
|||
when: avatarUrl !== ''
|
||||
value: avatarUrl
|
||||
}
|
||||
onSourceChanged: {
|
||||
console.debug('avatarImage: source = ', source);
|
||||
}
|
||||
|
||||
visible: avatarImage.status !== Image.Loading && avatarImage.status !== Image.Error
|
||||
}
|
||||
|
|
|
@ -96,9 +96,6 @@ Rectangle {
|
|||
AvatarThumbnail {
|
||||
id: avatarThumbnail
|
||||
avatarUrl: avatarImageUrl
|
||||
onAvatarUrlChanged: {
|
||||
console.debug('CreateFavoritesDialog: onAvatarUrlChanged: ', avatarUrl);
|
||||
}
|
||||
|
||||
wearablesCount: avatarWearablesCount
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@ Rectangle {
|
|||
property alias dialogButtons: buttons
|
||||
|
||||
property string imageSource: null
|
||||
onImageSourceChanged: {
|
||||
console.debug('imageSource = ', imageSource)
|
||||
}
|
||||
|
||||
property string button1color: hifi.buttons.noneBorderlessGray;
|
||||
property string button1text: ''
|
||||
|
|
|
@ -1094,7 +1094,7 @@ Rectangle {
|
|||
refreshBuyUI();
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
console.log('Checkout.qml: Unrecognized message from marketplaces.js');
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
|
|
|
@ -1867,7 +1867,7 @@ Item {
|
|||
sendAssetStep.selectedRecipientUserName = message.userName;
|
||||
break;
|
||||
default:
|
||||
console.log('SendAsset: Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||
console.log('SendAsset: Unrecognized message from wallet.js');
|
||||
}
|
||||
}
|
||||
signal sendSignalToParent(var msg);
|
||||
|
|
|
@ -597,7 +597,7 @@ Rectangle {
|
|||
resetCert(true);
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
console.log('InspectionCertificate.qml: Unrecognized message from marketplaces.js');
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
|
|
|
@ -1070,7 +1070,7 @@ Rectangle {
|
|||
http.handleHttpResponse(message);
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
console.log('Purchases.qml: Unrecognized message from marketplaces.js');
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
|
|
|
@ -250,7 +250,7 @@ At the moment, there is currently no way to convert HFC to other currencies. Sta
|
|||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
default:
|
||||
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||
console.log('Help.qml: Unrecognized message from wallet.js');
|
||||
}
|
||||
}
|
||||
signal sendSignalToWallet(var msg);
|
||||
|
|
|
@ -183,7 +183,7 @@ Item {
|
|||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
default:
|
||||
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||
console.log('NeedsLogIn.qml: Unrecognized message from wallet.js');
|
||||
}
|
||||
}
|
||||
signal sendSignalToWallet(var msg);
|
||||
|
|
|
@ -536,8 +536,8 @@ Rectangle {
|
|||
Rectangle {
|
||||
id: exchangeMoneyMessagesWaitingLight;
|
||||
visible: parent.messagesWaiting;
|
||||
anchors.right: exchangeMoneyTabIcon.left;
|
||||
anchors.rightMargin: 9;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.top: exchangeMoneyTabIcon.top;
|
||||
anchors.topMargin: 4;
|
||||
height: 10;
|
||||
|
@ -803,7 +803,7 @@ Rectangle {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||
console.log('Wallet.qml: Unrecognized message from wallet.js');
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
|
|
|
@ -130,17 +130,14 @@ ScrollingWindow {
|
|||
}
|
||||
|
||||
function loadScript(script) {
|
||||
console.log("Load script " + script);
|
||||
scripts.loadOneScript(script);
|
||||
}
|
||||
|
||||
function reloadScript(script) {
|
||||
console.log("Reload script " + script);
|
||||
scripts.stopScript(script, true);
|
||||
}
|
||||
|
||||
function stopScript(script) {
|
||||
console.log("Stop script " + script);
|
||||
scripts.stopScript(script);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,17 +120,14 @@ Rectangle {
|
|||
}
|
||||
|
||||
function loadScript(script) {
|
||||
console.log("Load script " + script);
|
||||
scripts.loadOneScript(script);
|
||||
}
|
||||
|
||||
function reloadScript(script) {
|
||||
console.log("Reload script " + script);
|
||||
scripts.stopScript(script, true);
|
||||
}
|
||||
|
||||
function stopScript(script) {
|
||||
console.log("Stop script " + script);
|
||||
scripts.stopScript(script);
|
||||
}
|
||||
|
||||
|
@ -158,7 +155,6 @@ Rectangle {
|
|||
console.log("Stop all scripts");
|
||||
for (var index = 0; index < runningScriptsModel.count; index++) {
|
||||
var url = runningScriptsModel.get(index).url;
|
||||
console.log(url);
|
||||
var fileName = url.substring(url.lastIndexOf('/')+1);
|
||||
if (canEditScript(fileName)) {
|
||||
scripts.stopScript(url);
|
||||
|
|
|
@ -130,9 +130,9 @@ ListModel {
|
|||
// Check consistency and call processPage.
|
||||
function handlePage(error, response, cb) {
|
||||
var processed;
|
||||
console.debug('handlePage', listModelName, additionalFirstPageRequested, error, JSON.stringify(response));
|
||||
console.debug('handlePage', listModelName, additionalFirstPageRequested, error);
|
||||
function fail(message) {
|
||||
console.warn("Warning page fail", listModelName, JSON.stringify(message));
|
||||
console.warn("Warning page fail", listModelName);
|
||||
currentPageToRetrieve = -1;
|
||||
requestPending = false;
|
||||
delayedClear = false;
|
||||
|
|
|
@ -285,7 +285,7 @@ TabBar {
|
|||
selectTab(message.params.id);
|
||||
break;
|
||||
default:
|
||||
console.warn('Unrecognized message:', JSON.stringify(message));
|
||||
console.warn('EditTabView.qml: Unrecognized message');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ TabBar {
|
|||
selectTab(message.params.id);
|
||||
break;
|
||||
default:
|
||||
console.warn('Unrecognized message:', JSON.stringify(message));
|
||||
console.warn('EditToolsTabView.qml: Unrecognized message');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -251,17 +251,29 @@ Item {
|
|||
height: 15
|
||||
|
||||
Rectangle {
|
||||
property bool isHovered: false
|
||||
anchors.centerIn: parent
|
||||
opacity: index === pageIndicator.currentIndex ? 0.95 : 0.45
|
||||
implicitWidth: index === pageIndicator.currentIndex ? 15 : 10
|
||||
opacity: index === pageIndicator.currentIndex || isHovered ? 0.95 : 0.45
|
||||
implicitWidth: index === pageIndicator.currentIndex || isHovered ? 15 : 10
|
||||
implicitHeight: implicitWidth
|
||||
radius: width/2
|
||||
color: "white"
|
||||
color: isHovered && index !== pageIndicator.currentIndex ? "#1fc6a6" : "white"
|
||||
Behavior on opacity {
|
||||
OpacityAnimator {
|
||||
duration: 100
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.centerIn: parent
|
||||
width: 20
|
||||
height: 30 // Make it easier to target with laser.
|
||||
hoverEnabled: true
|
||||
enabled: true
|
||||
onEntered: parent.isHovered = true;
|
||||
onExited: parent.isHovered = false;
|
||||
onClicked: swipeView.currentIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,6 @@ Rectangle {
|
|||
signal canceled();
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("Helper " + helper + " drives " + drives);
|
||||
|
||||
fileDialogItem.keyboardEnabled = HMD.active;
|
||||
|
||||
// HACK: The following lines force the model to initialize properly such that the go-up button
|
||||
|
@ -762,7 +760,6 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
console.log("Selecting " + selection)
|
||||
selectedFile(selection);
|
||||
//root.destroy();
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ Preference {
|
|||
});
|
||||
|
||||
browser.selectedFile.connect(function(fileUrl){
|
||||
console.log(fileUrl);
|
||||
dataTextField.text = fileDialogHelper.urlToPath(fileUrl);
|
||||
});
|
||||
|
||||
|
|
|
@ -73,6 +73,14 @@ void AndroidHelper::notifyHeadsetOn(bool pluggedIn) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void AndroidHelper::muteMic() {
|
||||
auto audioClient = DependencyManager::get<AudioClient>();
|
||||
if (audioClient) {
|
||||
QMetaObject::invokeMethod(audioClient.data(), "setMuted", Q_ARG(bool, true), Q_ARG(bool, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AndroidHelper::signup(QString email, QString username, QString password) {
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.callbackReceiver = this;
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
void performHapticFeedback(int duration);
|
||||
void processURL(const QString &url);
|
||||
void notifyHeadsetOn(bool pluggedIn);
|
||||
void muteMic();
|
||||
|
||||
AndroidHelper(AndroidHelper const&) = delete;
|
||||
void operator=(AndroidHelper const&) = delete;
|
||||
|
|
|
@ -387,6 +387,9 @@ static const QString ACTIVE_DISPLAY_PLUGIN_SETTING_NAME = "activeDisplayPlugin";
|
|||
static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system";
|
||||
static const QString KEEP_ME_LOGGED_IN_SETTING_NAME = "keepMeLoggedIn";
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
static const QString TESTER_FILE = "/sdcard/_hifi_test_device.txt";
|
||||
#endif
|
||||
const std::vector<std::pair<QString, Application::AcceptURLMethod>> Application::_acceptedExtensions {
|
||||
{ SVO_EXTENSION, &Application::importSVOFromURL },
|
||||
{ SVO_JSON_EXTENSION, &Application::importSVOFromURL },
|
||||
|
@ -993,6 +996,7 @@ const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false;
|
|||
const bool DEFAULT_PREFER_STYLUS_OVER_LASER = false;
|
||||
const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false;
|
||||
const QString DEFAULT_CURSOR_NAME = "DEFAULT";
|
||||
const bool DEFAULT_MINI_TABLET_ENABLED = true;
|
||||
|
||||
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runningMarkerExisted) :
|
||||
QApplication(argc, argv),
|
||||
|
@ -1012,6 +1016,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_preferAvatarFingerOverStylusSetting("preferAvatarFingerOverStylus", DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS),
|
||||
_constrainToolbarPosition("toolbar/constrainToolbarToCenterX", true),
|
||||
_preferredCursor("preferredCursor", DEFAULT_CURSOR_NAME),
|
||||
_miniTabletEnabledSetting("miniTabletEnabled", DEFAULT_MINI_TABLET_ENABLED),
|
||||
_scaleMirror(1.0f),
|
||||
_mirrorYawOffset(0.0f),
|
||||
_raiseMirror(0.0f),
|
||||
|
@ -1443,6 +1448,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
||||
static const QString TESTER = "HIFI_TESTER";
|
||||
bool isTester = false;
|
||||
#if defined (Q_OS_ANDROID)
|
||||
// Since we cannot set environment variables in Android we use a file presence
|
||||
// to denote that this is a testing device
|
||||
QFileInfo check_tester_file(TESTER_FILE);
|
||||
isTester = check_tester_file.exists() && check_tester_file.isFile();
|
||||
#endif
|
||||
|
||||
constexpr auto INSTALLER_INI_NAME = "installer.ini";
|
||||
auto iniPath = QDir(applicationDirPath()).filePath(INSTALLER_INI_NAME);
|
||||
QFile installerFile { iniPath };
|
||||
|
@ -1497,7 +1511,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
auto glContextData = getGLContextData();
|
||||
QJsonObject properties = {
|
||||
{ "version", applicationVersion() },
|
||||
{ "tester", QProcessEnvironment::systemEnvironment().contains(TESTER) },
|
||||
{ "tester", QProcessEnvironment::systemEnvironment().contains(TESTER) || isTester },
|
||||
{ "installer_campaign", installerCampaign },
|
||||
{ "installer_type", installerType },
|
||||
{ "build_type", BuildInfo::BUILD_TYPE_STRING },
|
||||
|
@ -2867,8 +2881,10 @@ void Application::initializeDisplayPlugins() {
|
|||
[this](const QSize& size) { resizeGL(); });
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset);
|
||||
if (displayPlugin->isHmd()) {
|
||||
QObject::connect(dynamic_cast<HmdDisplayPlugin*>(displayPlugin.get()), &HmdDisplayPlugin::hmdMountedChanged,
|
||||
auto hmdDisplayPlugin = dynamic_cast<HmdDisplayPlugin*>(displayPlugin.get());
|
||||
QObject::connect(hmdDisplayPlugin, &HmdDisplayPlugin::hmdMountedChanged,
|
||||
DependencyManager::get<HMDScriptingInterface>().data(), &HMDScriptingInterface::mountedChanged);
|
||||
QObject::connect(hmdDisplayPlugin, &HmdDisplayPlugin::hmdVisibleChanged, this, &Application::hmdVisibleChanged);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3391,6 +3407,11 @@ void Application::setSettingConstrainToolbarPosition(bool setting) {
|
|||
DependencyManager::get<OffscreenUi>()->setConstrainToolbarToCenterX(setting);
|
||||
}
|
||||
|
||||
void Application::setMiniTabletEnabled(bool enabled) {
|
||||
_miniTabletEnabledSetting.set(enabled);
|
||||
emit miniTabletEnabledChanged(enabled);
|
||||
}
|
||||
|
||||
void Application::showHelp() {
|
||||
static const QString HAND_CONTROLLER_NAME_VIVE = "vive";
|
||||
static const QString HAND_CONTROLLER_NAME_OCULUS_TOUCH = "oculus";
|
||||
|
@ -3537,7 +3558,17 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
|||
|
||||
} else {
|
||||
#if !defined(Q_OS_ANDROID)
|
||||
qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString);
|
||||
QString goingTo = "";
|
||||
if (addressLookupString.isEmpty()) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HomeLocation)) {
|
||||
auto locationBookmarks = DependencyManager::get<LocationBookmarks>();
|
||||
addressLookupString = locationBookmarks->addressForBookmark(LocationBookmarks::HOME_BOOKMARK);
|
||||
goingTo = "home location";
|
||||
} else {
|
||||
goingTo = "previous location";
|
||||
}
|
||||
}
|
||||
qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(!goingTo.isEmpty() ? goingTo : addressLookupString);
|
||||
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
|
||||
sentTo = SENT_TO_PREVIOUS_LOCATION;
|
||||
#endif
|
||||
|
@ -6074,9 +6105,7 @@ void Application::update(float deltaTime) {
|
|||
{
|
||||
PROFILE_RANGE_EX(app, "Overlays", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
PerformanceTimer perfTimer("overlays");
|
||||
if (qApp->shouldPaint()) {
|
||||
_overlays.update(deltaTime);
|
||||
}
|
||||
_overlays.update(deltaTime);
|
||||
}
|
||||
|
||||
// Update _viewFrustum with latest camera and view frustum data...
|
||||
|
@ -6161,10 +6190,8 @@ void Application::update(float deltaTime) {
|
|||
PROFILE_RANGE_EX(app, "PostUpdateLambdas", 0xffff0000, (uint64_t)0);
|
||||
PerformanceTimer perfTimer("postUpdateLambdas");
|
||||
std::unique_lock<std::mutex> guard(_postUpdateLambdasLock);
|
||||
if (qApp->shouldPaint()) {
|
||||
for (auto& iter : _postUpdateLambdas) {
|
||||
iter.second();
|
||||
}
|
||||
for (auto& iter : _postUpdateLambdas) {
|
||||
iter.second();
|
||||
}
|
||||
_postUpdateLambdas.clear();
|
||||
}
|
||||
|
@ -6502,15 +6529,26 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const {
|
|||
viewOut = _displayViewFrustum;
|
||||
}
|
||||
|
||||
// resentSensors() is a bit of vestigial feature. It used to be used for Oculus DK2 to recenter the view around
|
||||
// the current head orientation. With the introduction of "room scale" tracking we no longer need that particular
|
||||
// feature. However, we still use this to reset face trackers, eye trackers, audio and to optionally re-load the avatar
|
||||
// rig and animations from scratch.
|
||||
void Application::resetSensors(bool andReload) {
|
||||
DependencyManager::get<DdeFaceTracker>()->reset();
|
||||
DependencyManager::get<EyeTracker>()->reset();
|
||||
getActiveDisplayPlugin()->resetSensors();
|
||||
_overlayConductor.centerUI();
|
||||
getMyAvatar()->reset(true, andReload);
|
||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void Application::hmdVisibleChanged(bool visible) {
|
||||
if (visible) {
|
||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "start", Qt::QueuedConnection);
|
||||
} else {
|
||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "stop", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateWindowTitle() const {
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
@ -7005,7 +7043,7 @@ bool Application::askToSetAvatarUrl(const QString& url) {
|
|||
getMyAvatar()->useFullAvatarURL(url, modelName);
|
||||
emit fullAvatarURLChanged(url, modelName);
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "Declined to use the avatar: " << url;
|
||||
qCDebug(interfaceapp) << "Declined to use the avatar";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -7033,7 +7071,7 @@ bool Application::askToSetAvatarUrl(const QString& url) {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "Declined to agree to avatar license: " << url;
|
||||
qCDebug(interfaceapp) << "Declined to agree to avatar license";
|
||||
}
|
||||
|
||||
//auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
@ -7070,7 +7108,7 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) {
|
|||
qCDebug(interfaceapp) << "Chose to run the script: " << fileName;
|
||||
DependencyManager::get<ScriptEngines>()->loadScript(fileName);
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "Declined to run the script: " << scriptFilenameOrURL;
|
||||
qCDebug(interfaceapp) << "Declined to run the script";
|
||||
}
|
||||
QObject::disconnect(dlg, &ModalDialogListener::response, this, nullptr);
|
||||
});
|
||||
|
@ -7128,7 +7166,7 @@ bool Application::askToWearAvatarAttachmentUrl(const QString& url) {
|
|||
attachmentDataVec.push_back(attachmentData);
|
||||
myAvatar->setAttachmentData(attachmentDataVec);
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "User declined to wear the avatar attachment: " << url;
|
||||
qCDebug(interfaceapp) << "User declined to wear the avatar attachment";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -7147,7 +7185,7 @@ bool Application::askToWearAvatarAttachmentUrl(const QString& url) {
|
|||
}
|
||||
|
||||
void Application::replaceDomainContent(const QString& url) {
|
||||
qCDebug(interfaceapp) << "Attempting to replace domain content: " << url;
|
||||
qCDebug(interfaceapp) << "Attempting to replace domain content";
|
||||
QByteArray urlData(url.toUtf8());
|
||||
auto limitedNodeList = DependencyManager::get<NodeList>();
|
||||
const auto& domainHandler = limitedNodeList->getDomainHandler();
|
||||
|
@ -7275,7 +7313,6 @@ void Application::showAssetServerWidget(QString filePath) {
|
|||
}
|
||||
|
||||
void Application::addAssetToWorldFromURL(QString url) {
|
||||
qInfo(interfaceapp) << "Download model and add to world from" << url;
|
||||
|
||||
QString filename;
|
||||
if (url.contains("filename")) {
|
||||
|
@ -7328,13 +7365,11 @@ void Application::addAssetToWorldFromURLRequestFinished() {
|
|||
}
|
||||
|
||||
if (result == ResourceRequest::Success) {
|
||||
qInfo(interfaceapp) << "Downloaded model from" << url;
|
||||
QTemporaryDir temporaryDir;
|
||||
temporaryDir.setAutoRemove(false);
|
||||
if (temporaryDir.isValid()) {
|
||||
QString temporaryDirPath = temporaryDir.path();
|
||||
QString downloadPath = temporaryDirPath + "/" + filename;
|
||||
qInfo(interfaceapp) << "Download path:" << downloadPath;
|
||||
|
||||
QFile tempFile(downloadPath);
|
||||
if (tempFile.open(QIODevice::WriteOnly)) {
|
||||
|
|
|
@ -228,6 +228,9 @@ public:
|
|||
bool getPreferAvatarFingerOverStylus() { return false; }
|
||||
void setPreferAvatarFingerOverStylus(bool value);
|
||||
|
||||
bool getMiniTabletEnabled() { return _miniTabletEnabledSetting.get(); }
|
||||
void setMiniTabletEnabled(bool enabled);
|
||||
|
||||
float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); }
|
||||
void setSettingConstrainToolbarPosition(bool setting);
|
||||
|
||||
|
@ -338,6 +341,8 @@ signals:
|
|||
|
||||
void loginDialogPoppedUp();
|
||||
|
||||
void miniTabletEnabledChanged(bool enabled);
|
||||
|
||||
public slots:
|
||||
QVector<EntityItemID> pasteEntities(float x, float y, float z);
|
||||
bool exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs, const glm::vec3* givenOffset = nullptr);
|
||||
|
@ -382,6 +387,8 @@ public slots:
|
|||
void resetSensors(bool andReload = false);
|
||||
void setActiveFaceTracker() const;
|
||||
|
||||
void hmdVisibleChanged(bool visible);
|
||||
|
||||
#if (PR_BUILD || DEV_BUILD)
|
||||
void sendWrongProtocolVersionsSignature(bool checked) { ::sendWrongProtocolVersionsSignature(checked); }
|
||||
#endif
|
||||
|
@ -629,6 +636,7 @@ private:
|
|||
Setting::Handle<bool> _preferAvatarFingerOverStylusSetting;
|
||||
Setting::Handle<bool> _constrainToolbarPosition;
|
||||
Setting::Handle<QString> _preferredCursor;
|
||||
Setting::Handle<bool> _miniTabletEnabledSetting;
|
||||
|
||||
float _scaleMirror;
|
||||
float _mirrorYawOffset;
|
||||
|
|
|
@ -180,7 +180,7 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) {
|
|||
myAvatar->removeWearableAvatarEntities();
|
||||
const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString();
|
||||
myAvatar->useFullAvatarURL(avatarUrl);
|
||||
qCDebug(interfaceapp) << "Avatar On " << avatarUrl;
|
||||
qCDebug(interfaceapp) << "Avatar On";
|
||||
const QList<QVariant>& attachments = bookmark.value(ENTRY_AVATAR_ATTACHMENTS, QList<QVariant>()).toList();
|
||||
|
||||
qCDebug(interfaceapp) << "Attach " << attachments;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <SettingHandle.h>
|
||||
#include <OctreeUtils.h>
|
||||
#include <Util.h>
|
||||
#include <shared/GlobalAppProperties.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ui/DialogsManager.h"
|
||||
|
@ -309,7 +310,13 @@ QString LODManager::getLODFeedbackText() {
|
|||
|
||||
void LODManager::loadSettings() {
|
||||
setDesktopLODTargetFPS(desktopLODDecreaseFPS.get());
|
||||
setHMDLODTargetFPS(hmdLODDecreaseFPS.get());
|
||||
Setting::Handle<bool> firstRun { Settings::firstRun, true };
|
||||
if (qApp->property(hifi::properties::OCULUS_STORE).toBool() && firstRun.get()) {
|
||||
const float LOD_HIGH_QUALITY_LEVEL = 0.75f;
|
||||
setHMDLODTargetFPS(LOD_HIGH_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS);
|
||||
} else {
|
||||
setHMDLODTargetFPS(hmdLODDecreaseFPS.get());
|
||||
}
|
||||
}
|
||||
|
||||
void LODManager::saveSettings() {
|
||||
|
|
|
@ -226,6 +226,14 @@ Menu::Menu() {
|
|||
addActionToQMenuAndActionHash(navigateMenu, MenuOption::CopyPath, 0,
|
||||
addressManager.data(), SLOT(copyPath()));
|
||||
|
||||
// Navigate > Start-up Location
|
||||
MenuWrapper* startupLocationMenu = navigateMenu->addMenu(MenuOption::StartUpLocation);
|
||||
QActionGroup* startupLocatiopnGroup = new QActionGroup(startupLocationMenu);
|
||||
startupLocatiopnGroup->setExclusive(true);
|
||||
startupLocatiopnGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::HomeLocation, 0,
|
||||
false));
|
||||
startupLocatiopnGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::LastLocation, 0,
|
||||
true));
|
||||
|
||||
// Settings menu ----------------------------------
|
||||
MenuWrapper* settingsMenu = addMenu("Settings");
|
||||
|
|
|
@ -117,9 +117,11 @@ namespace MenuOption {
|
|||
const QString FrameTimer = "Show Timer";
|
||||
const QString FullscreenMirror = "Mirror";
|
||||
const QString Help = "Help...";
|
||||
const QString HomeLocation = "Home";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IndependentMode = "Independent Mode";
|
||||
const QString ActionMotorControl = "Enable Default Motor Control";
|
||||
const QString LastLocation = "Last Location";
|
||||
const QString LoadScript = "Open and Run Script File...";
|
||||
const QString LoadScriptURL = "Open and Run Script from URL...";
|
||||
const QString LodTools = "LOD Tools";
|
||||
|
@ -197,6 +199,7 @@ namespace MenuOption {
|
|||
const QString SimulateEyeTracking = "Simulate";
|
||||
const QString SMIEyeTracking = "SMI Eye Tracking";
|
||||
const QString SparseTextureManagement = "Enable Sparse Texture Management";
|
||||
const QString StartUpLocation = "Start-Up Location";
|
||||
const QString Stats = "Show Statistics";
|
||||
const QString AnimStats = "Show Animation Stats";
|
||||
const QString StopAllScripts = "Stop All Scripts";
|
||||
|
|
|
@ -86,7 +86,7 @@ bool ModelPackager::loadModel() {
|
|||
qWarning() << QString("ModelPackager::loadModel(): Could not open FST file %1").arg(_modelFile.filePath());
|
||||
return false;
|
||||
}
|
||||
qCDebug(interfaceapp) << "Reading FST file : " << _modelFile.filePath();
|
||||
qCDebug(interfaceapp) << "Reading FST file";
|
||||
_mapping = FSTReader::readMapping(fst.readAll());
|
||||
fst.close();
|
||||
|
||||
|
@ -102,7 +102,7 @@ bool ModelPackager::loadModel() {
|
|||
QString("ModelPackager::loadModel()"),
|
||||
QString("Could not open FBX file %1").arg(_fbxInfo.filePath()),
|
||||
QMessageBox::Ok);
|
||||
qWarning() << QString("ModelPackager::loadModel(): Could not open FBX file %1").arg(_fbxInfo.filePath());
|
||||
qWarning() << "ModelPackager::loadModel(): Could not open FBX file";
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
|
@ -114,7 +114,7 @@ bool ModelPackager::loadModel() {
|
|||
// make sure we have some basic mappings
|
||||
populateBasicMapping(_mapping, _fbxInfo.filePath(), *_hfmModel);
|
||||
} catch (const QString& error) {
|
||||
qCDebug(interfaceapp) << "Error reading " << _fbxInfo.filePath() << ": " << error;
|
||||
qCDebug(interfaceapp) << "Error reading: " << error;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -132,7 +132,7 @@ bool ModelPackager::editProperties() {
|
|||
// Make sure that a mapping for the root joint has been specified
|
||||
QVariantHash joints = _mapping.value(JOINT_FIELD).toHash();
|
||||
if (!joints.contains("jointRoot")) {
|
||||
qWarning() << QString("%1 root joint not configured for skeleton.").arg(_modelFile.fileName());
|
||||
qWarning() << "root joint not configured for skeleton.";
|
||||
|
||||
QString message = "Your did not configure a root joint for your skeleton model.\n\nPackaging will be canceled.";
|
||||
QMessageBox msgBox;
|
||||
|
@ -235,7 +235,7 @@ bool ModelPackager::zipModel() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename, const HFMModel& hfmModel) {
|
||||
void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename, const hfm::Model& hfmModel) {
|
||||
|
||||
bool isBodyType = _modelType == FSTReader::BODY_ONLY_MODEL || _modelType == FSTReader::HEAD_AND_BODY_MODEL;
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
|
||||
#include "ui/ModelsBrowser.h"
|
||||
|
||||
class HFMModel;
|
||||
namespace hfm {
|
||||
class Model;
|
||||
};
|
||||
|
||||
class ModelPackager : public QObject {
|
||||
public:
|
||||
|
@ -32,7 +34,7 @@ private:
|
|||
bool editProperties();
|
||||
bool zipModel();
|
||||
|
||||
void populateBasicMapping(QVariantHash& mapping, QString filename, const HFMModel& hfmModel);
|
||||
void populateBasicMapping(QVariantHash& mapping, QString filename, const hfm::Model& hfmModel);
|
||||
|
||||
void listTextures();
|
||||
bool copyTextures(const QString& oldDir, const QDir& newDir);
|
||||
|
@ -44,7 +46,7 @@ private:
|
|||
QString _scriptDir;
|
||||
|
||||
QVariantHash _mapping;
|
||||
std::unique_ptr<HFMModel> _hfmModel;
|
||||
std::unique_ptr<hfm::Model> _hfmModel;
|
||||
QStringList _textures;
|
||||
QStringList _scripts;
|
||||
};
|
||||
|
|
|
@ -69,7 +69,7 @@ void ATPAssetMigrator::loadEntityServerFile() {
|
|||
} else {
|
||||
++_errorCount;
|
||||
_pendingReplacements.remove(migrationURL);
|
||||
qWarning() << "Could not retrieve asset at" << migrationURL.toString();
|
||||
qWarning() << "Could not retrieve asset";
|
||||
|
||||
checkIfFinished();
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ void ATPAssetMigrator::loadEntityServerFile() {
|
|||
request->send();
|
||||
} else {
|
||||
++_errorCount;
|
||||
qWarning() << "Could not create request for asset at" << migrationURL.toString();
|
||||
qWarning() << "Could not create request for asset";
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -239,7 +239,7 @@ void ATPAssetMigrator::assetUploadFinished(AssetUpload *upload, const QString& h
|
|||
_pendingReplacements.remove(migrationURL);
|
||||
|
||||
++_errorCount;
|
||||
qWarning() << "Failed to upload" << migrationURL << "- error was" << upload->getErrorString();
|
||||
qWarning() << "Failed to upload" << "- error was" << upload->getErrorString();
|
||||
}
|
||||
|
||||
checkIfFinished();
|
||||
|
@ -281,7 +281,7 @@ void ATPAssetMigrator::setMappingFinished(SetMappingRequest* request) {
|
|||
_pendingReplacements.remove(migrationURL);
|
||||
|
||||
++_errorCount;
|
||||
qWarning() << "Error setting mapping for" << migrationURL << "- error was " << request->getErrorString();
|
||||
qWarning() << "Error setting mapping for" << "- error was " << request->getErrorString();
|
||||
}
|
||||
|
||||
checkIfFinished();
|
||||
|
|
|
@ -471,7 +471,7 @@ void MyAvatar::updateSitStandState(float newHeightReading, float dt) {
|
|||
const float STANDING_TIMEOUT = 0.3333f; // 1/3 second
|
||||
const float SITTING_UPPER_BOUND = 1.52f;
|
||||
if (!getIsSitStandStateLocked()) {
|
||||
if (!getIsAway() && qApp->isHMDMode()) {
|
||||
if (!getIsAway() && getControllerPoseInAvatarFrame(controller::Action::HEAD).isValid()) {
|
||||
if (getIsInSittingState()) {
|
||||
if (newHeightReading > (STANDING_HEIGHT_MULTIPLE * _tippingPoint)) {
|
||||
// if we recenter upwards then no longer in sitting state
|
||||
|
@ -538,17 +538,25 @@ void MyAvatar::update(float deltaTime) {
|
|||
|
||||
// put the average hand azimuth into sensor space.
|
||||
// then mix it with head facing direction to determine rotation recenter
|
||||
if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) {
|
||||
glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y));
|
||||
int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2");
|
||||
if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && !(spine2Index < 0)) {
|
||||
|
||||
// use the spine for the azimuth origin.
|
||||
glm::quat spine2Rot = getAbsoluteJointRotationInObjectFrame(spine2Index);
|
||||
glm::vec3 handHipAzimuthAvatarSpace = spine2Rot * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y);
|
||||
glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), handHipAzimuthAvatarSpace);
|
||||
glm::mat4 sensorToWorldMat = getSensorToWorldMatrix();
|
||||
glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat);
|
||||
glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace);
|
||||
glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f);
|
||||
if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) {
|
||||
normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z));
|
||||
glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH);
|
||||
_headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau);
|
||||
} else {
|
||||
// use head facing if the chest arms vector is up or down.
|
||||
_headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau);
|
||||
}
|
||||
glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH);
|
||||
_headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau);
|
||||
} else {
|
||||
_headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau);
|
||||
}
|
||||
|
@ -576,7 +584,11 @@ void MyAvatar::update(float deltaTime) {
|
|||
upSpine2 = glm::normalize(upSpine2);
|
||||
}
|
||||
float angleSpine2 = glm::dot(upSpine2, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
if (getControllerPoseInAvatarFrame(controller::Action::HEAD).getTranslation().y < (headDefaultPositionAvatarSpace.y - SQUAT_THRESHOLD) && (angleSpine2 > COSINE_THIRTY_DEGREES)) {
|
||||
|
||||
if (getControllerPoseInAvatarFrame(controller::Action::HEAD).getTranslation().y < (headDefaultPositionAvatarSpace.y - SQUAT_THRESHOLD) &&
|
||||
(angleSpine2 > COSINE_THIRTY_DEGREES) &&
|
||||
(getUserRecenterModel() != MyAvatar::SitStandModelType::ForceStand)) {
|
||||
|
||||
_squatTimer += deltaTime;
|
||||
if (_squatTimer > SQUATTY_TIMEOUT) {
|
||||
_squatTimer = 0.0f;
|
||||
|
@ -720,6 +732,10 @@ void MyAvatar::recalculateChildCauterization() const {
|
|||
_cauterizationNeedsUpdate = true;
|
||||
}
|
||||
|
||||
bool MyAvatar::isFollowActive(FollowHelper::FollowType followType) const {
|
||||
return _follow.isActive(followType);
|
||||
}
|
||||
|
||||
void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object, bool cauterize) {
|
||||
if (object->getNestableType() == NestableType::Entity) {
|
||||
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
|
||||
|
@ -979,35 +995,48 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) {
|
|||
}
|
||||
|
||||
// Find the vector halfway between the hip to hand azimuth vectors
|
||||
// This midpoint hand azimuth is in Avatar space
|
||||
// This midpoint hand azimuth is in Spine2 space
|
||||
glm::vec2 MyAvatar::computeHandAzimuth() const {
|
||||
controller::Pose leftHandPoseAvatarSpace = getLeftHandPose();
|
||||
controller::Pose rightHandPoseAvatarSpace = getRightHandPose();
|
||||
controller::Pose headPoseAvatarSpace = getControllerPoseInAvatarFrame(controller::Action::HEAD);
|
||||
const float HALFWAY = 0.50f;
|
||||
|
||||
glm::vec2 latestHipToHandController = _hipToHandController;
|
||||
|
||||
if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid() && headPoseAvatarSpace.isValid()) {
|
||||
int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2");
|
||||
if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid() && headPoseAvatarSpace.isValid() && !(spine2Index < 0)) {
|
||||
|
||||
glm::vec3 spine2Position = getAbsoluteJointTranslationInObjectFrame(spine2Index);
|
||||
glm::quat spine2Rotation = getAbsoluteJointRotationInObjectFrame(spine2Index);
|
||||
|
||||
glm::vec3 rightHandOffset = rightHandPoseAvatarSpace.translation - spine2Position;
|
||||
glm::vec3 leftHandOffset = leftHandPoseAvatarSpace.translation - spine2Position;
|
||||
glm::vec3 rightHandSpine2Space = glm::inverse(spine2Rotation) * rightHandOffset;
|
||||
glm::vec3 leftHandSpine2Space = glm::inverse(spine2Rotation) * leftHandOffset;
|
||||
|
||||
// we need the old azimuth reading to prevent flipping the facing direction 180
|
||||
// in the case where the hands go from being slightly less than 180 apart to slightly more than 180 apart.
|
||||
glm::vec2 oldAzimuthReading = _hipToHandController;
|
||||
if ((glm::length(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)) > 0.0f) && (glm::length(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)) > 0.0f)) {
|
||||
latestHipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY);
|
||||
if ((glm::length(glm::vec2(rightHandSpine2Space.x, rightHandSpine2Space.z)) > 0.0f) && (glm::length(glm::vec2(leftHandSpine2Space.x, leftHandSpine2Space.z)) > 0.0f)) {
|
||||
latestHipToHandController = lerp(glm::normalize(glm::vec2(rightHandSpine2Space.x, rightHandSpine2Space.z)), glm::normalize(glm::vec2(leftHandSpine2Space.x, leftHandSpine2Space.z)), HALFWAY);
|
||||
} else {
|
||||
latestHipToHandController = glm::vec2(0.0f, -1.0f);
|
||||
latestHipToHandController = glm::vec2(0.0f, 1.0f);
|
||||
}
|
||||
|
||||
glm::vec3 headLookAtAvatarSpace = transformVectorFast(headPoseAvatarSpace.getMatrix(), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
glm::vec2 headAzimuthAvatarSpace = glm::vec2(headLookAtAvatarSpace.x, headLookAtAvatarSpace.z);
|
||||
if (glm::length(headAzimuthAvatarSpace) > 0.0f) {
|
||||
headAzimuthAvatarSpace = glm::normalize(headAzimuthAvatarSpace);
|
||||
glm::vec3 headLookAtSpine2Space = glm::inverse(spine2Rotation) * headLookAtAvatarSpace;
|
||||
|
||||
glm::vec2 headAzimuthSpine2Space = glm::vec2(headLookAtSpine2Space.x, headLookAtSpine2Space.z);
|
||||
if (glm::length(headAzimuthSpine2Space) > 0.0f) {
|
||||
headAzimuthSpine2Space = glm::normalize(headAzimuthSpine2Space);
|
||||
} else {
|
||||
headAzimuthAvatarSpace = -latestHipToHandController;
|
||||
headAzimuthSpine2Space = -latestHipToHandController;
|
||||
}
|
||||
|
||||
// check the angular distance from forward and back
|
||||
float cosForwardAngle = glm::dot(latestHipToHandController, oldAzimuthReading);
|
||||
float cosHeadShoulder = glm::dot(-latestHipToHandController, headAzimuthAvatarSpace);
|
||||
float cosHeadShoulder = glm::dot(-latestHipToHandController, headAzimuthSpine2Space);
|
||||
// if we are now closer to the 180 flip of the previous chest forward
|
||||
// then we negate our computed latestHipToHandController to keep the chest from flipping.
|
||||
// also check the head to shoulder azimuth difference if we negate.
|
||||
|
@ -1067,9 +1096,9 @@ void MyAvatar::updateSensorToWorldMatrix() {
|
|||
void MyAvatar::updateFromTrackers(float deltaTime) {
|
||||
glm::vec3 estimatedRotation;
|
||||
|
||||
bool inHmd = qApp->isHMDMode();
|
||||
bool hasHead = getControllerPoseInAvatarFrame(controller::Action::HEAD).isValid();
|
||||
bool playing = DependencyManager::get<recording::Deck>()->isPlaying();
|
||||
if (inHmd && playing) {
|
||||
if (hasHead && playing) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1103,7 +1132,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
|
||||
|
||||
Head* head = getHead();
|
||||
if (inHmd || playing) {
|
||||
if (hasHead || playing) {
|
||||
head->setDeltaPitch(estimatedRotation.x);
|
||||
head->setDeltaYaw(estimatedRotation.y);
|
||||
head->setDeltaRoll(estimatedRotation.z);
|
||||
|
@ -1464,7 +1493,7 @@ void MyAvatar::loadData() {
|
|||
_yawSpeed = _yawSpeedSetting.get(_yawSpeed);
|
||||
_pitchSpeed = _pitchSpeedSetting.get(_pitchSpeed);
|
||||
|
||||
_prefOverrideAnimGraphUrl.set(_prefOverrideAnimGraphUrl.get().toString());
|
||||
_prefOverrideAnimGraphUrl.set(_animGraphURLSetting.get().toString());
|
||||
_fullAvatarURLFromPreferences = _fullAvatarURLSetting.get(QUrl(AvatarData::defaultFullAvatarModelUrl()));
|
||||
_fullAvatarModelName = _fullAvatarModelNameSetting.get(DEFAULT_FULL_AVATAR_MODEL_NAME).toString();
|
||||
|
||||
|
@ -3478,7 +3507,7 @@ void MyAvatar::triggerRotationRecenter() {
|
|||
|
||||
// old school meat hook style
|
||||
glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const {
|
||||
glm::vec3 headPosition;
|
||||
glm::vec3 headPosition(0.0f, _userHeight.get(), 0.0f);
|
||||
glm::quat headOrientation;
|
||||
auto headPose = getControllerPoseInSensorFrame(controller::Action::HEAD);
|
||||
if (headPose.isValid()) {
|
||||
|
@ -3518,19 +3547,33 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const {
|
|||
}
|
||||
|
||||
glm::mat4 MyAvatar::getSpine2RotationRigSpace() const {
|
||||
int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2");
|
||||
glm::quat spine2Rot = Quaternions::IDENTITY;
|
||||
if (!(spine2Index < 0)) {
|
||||
// use the spine for the azimuth origin.
|
||||
spine2Rot = getAbsoluteJointRotationInObjectFrame(spine2Index);
|
||||
}
|
||||
glm::vec3 spine2UpAvatarSpace = spine2Rot * glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 spine2FwdAvatarSpace = spine2Rot * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y);
|
||||
|
||||
// static const glm::quat RIG_CHANGE_OF_BASIS = Quaternions::Y_180;
|
||||
// RIG_CHANGE_OF_BASIS * AVATAR_TO_RIG_ROTATION * inverse(RIG_CHANGE_OF_BASIS) = Quaternions::Y_180; //avatar Space;
|
||||
const glm::quat AVATAR_TO_RIG_ROTATION = Quaternions::Y_180;
|
||||
glm::vec3 hipToHandRigSpace = AVATAR_TO_RIG_ROTATION * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y);
|
||||
glm::vec3 spine2UpRigSpace = AVATAR_TO_RIG_ROTATION * spine2UpAvatarSpace;
|
||||
glm::vec3 spine2FwdRigSpace = AVATAR_TO_RIG_ROTATION * spine2FwdAvatarSpace;
|
||||
|
||||
glm::vec3 u, v, w;
|
||||
if (glm::length(hipToHandRigSpace) > 0.0f) {
|
||||
hipToHandRigSpace = glm::normalize(hipToHandRigSpace);
|
||||
if (glm::length(spine2FwdRigSpace) > 0.0f) {
|
||||
spine2FwdRigSpace = glm::normalize(spine2FwdRigSpace);
|
||||
} else {
|
||||
hipToHandRigSpace = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||
spine2FwdRigSpace = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w);
|
||||
if (glm::length(spine2UpRigSpace) > 0.0f) {
|
||||
spine2UpRigSpace = glm::normalize(spine2UpRigSpace);
|
||||
} else {
|
||||
spine2UpRigSpace = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
generateBasisVectors(spine2UpRigSpace, spine2FwdRigSpace, u, v, w);
|
||||
glm::mat4 spine2RigSpace(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f));
|
||||
return spine2RigSpace;
|
||||
}
|
||||
|
@ -3797,7 +3840,7 @@ float MyAvatar::computeStandingHeightMode(const controller::Pose& head) {
|
|||
modeInMeters = ((float)mode) / CENTIMETERS_PER_METER;
|
||||
if (!(modeInMeters > getCurrentStandingHeight())) {
|
||||
// if not greater check for a reset
|
||||
if (getResetMode() && qApp->isHMDMode()) {
|
||||
if (getResetMode() && getControllerPoseInAvatarFrame(controller::Action::HEAD).isValid()) {
|
||||
setResetMode(false);
|
||||
float resetModeInCentimeters = glm::floor((head.getTranslation().y - MODE_CORRECTION_FACTOR)*CENTIMETERS_PER_METER);
|
||||
modeInMeters = (resetModeInCentimeters / CENTIMETERS_PER_METER);
|
||||
|
|
|
@ -54,6 +54,7 @@ Q_DECLARE_METATYPE(AudioListenerMode);
|
|||
|
||||
class MyAvatar : public Avatar {
|
||||
Q_OBJECT
|
||||
friend class AnimStats;
|
||||
|
||||
/**jsdoc
|
||||
* Your avatar is your in-world representation of you. The <code>MyAvatar</code> API is used to manipulate the avatar.
|
||||
|
@ -1163,7 +1164,7 @@ public:
|
|||
virtual QVariantList getAttachmentsVariant() const override;
|
||||
virtual void setAttachmentsVariant(const QVariantList& variant) override;
|
||||
|
||||
glm::vec3 getNextPosition() { return _goToPending ? _goToPosition : getWorldPosition(); };
|
||||
glm::vec3 getNextPosition() { return _goToPending ? _goToPosition : getWorldPosition(); }
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -1731,7 +1732,7 @@ private:
|
|||
glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space)
|
||||
glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
glm::vec2 _hipToHandController { 0.0f, -1.0f }; // spine2 facing vector in xz plane (avatar space)
|
||||
glm::vec2 _hipToHandController { 0.0f, 1.0f }; // spine2 facing vector in xz plane (spine2 space)
|
||||
|
||||
float _currentStandingHeight { 0.0f };
|
||||
bool _resetMode { true };
|
||||
|
@ -1780,8 +1781,11 @@ private:
|
|||
std::atomic<bool> _forceActivateHorizontal { false };
|
||||
std::atomic<bool> _toggleHipsFollowing { true };
|
||||
};
|
||||
|
||||
FollowHelper _follow;
|
||||
|
||||
bool isFollowActive(FollowHelper::FollowType followType) const;
|
||||
|
||||
bool _goToPending { false };
|
||||
bool _physicsSafetyPending { false };
|
||||
bool _goToSafe { true };
|
||||
|
|
|
@ -36,7 +36,6 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle
|
|||
static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
||||
glm::mat4 worldToSensorMat = glm::inverse(myAvatar->getSensorToWorldMatrix());
|
||||
|
||||
|
||||
// check for pinned hips.
|
||||
auto hipsIndex = myAvatar->getJointIndex("Hips");
|
||||
if (myAvatar->isJointPinned(hipsIndex)) {
|
||||
|
@ -57,6 +56,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
|||
glm::vec3 hipsPos = extractTranslation(hipsMat);
|
||||
glm::quat hipsRot = glmExtractRotation(hipsMat);
|
||||
|
||||
|
||||
glm::mat4 avatarToWorldMat = myAvatar->getTransform().getMatrix();
|
||||
glm::mat4 avatarToSensorMat = worldToSensorMat * avatarToWorldMat;
|
||||
|
||||
|
@ -233,6 +233,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() &&
|
||||
!(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) {
|
||||
|
||||
const float SPINE2_ROTATION_FILTER = 0.5f;
|
||||
AnimPose currentSpine2Pose;
|
||||
AnimPose currentHeadPose;
|
||||
AnimPose currentHipsPose;
|
||||
|
@ -252,7 +253,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
}
|
||||
generateBasisVectors(up, fwd, u, v, w);
|
||||
AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)));
|
||||
currentSpine2Pose.rot() = newSpinePose.rot();
|
||||
currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER);
|
||||
params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose;
|
||||
params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ void Ledger::send(const QString& endpoint, const QString& success, const QString
|
|||
const QString URL = "/api/v1/commerce/";
|
||||
JSONCallbackParameters callbackParams(this, success, fail);
|
||||
#if defined(DEV_BUILD) // Don't expose user's personal data in the wild. But during development this can be handy.
|
||||
qCInfo(commerce) << "Sending" << endpoint << QJsonDocument(request).toJson(QJsonDocument::Compact);
|
||||
qCInfo(commerce) << "Sending" << QJsonDocument(request).toJson(QJsonDocument::Compact);
|
||||
#endif
|
||||
accountManager->sendRequest(URL + endpoint,
|
||||
authType,
|
||||
|
|
|
@ -396,8 +396,7 @@ bool QmlCommerce::uninstallApp(const QString& itemHref) {
|
|||
QString scriptUrl = appFileJsonObject["scriptURL"].toString();
|
||||
|
||||
if (!DependencyManager::get<ScriptEngines>()->stopScript(scriptUrl.trimmed(), false)) {
|
||||
qCWarning(commerce) << "Couldn't stop script during app uninstall. Continuing anyway. ScriptURL is:"
|
||||
<< scriptUrl.trimmed();
|
||||
qCWarning(commerce) << "Couldn't stop script during app uninstall. Continuing anyway.";
|
||||
}
|
||||
|
||||
// Delete the .app.json from the filesystem
|
||||
|
|
|
@ -225,7 +225,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
|
|||
}
|
||||
const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6;
|
||||
if (totalNumVertices > MAX_VERTICES_PER_STATIC_MESH) {
|
||||
qWarning() << "model" << resource->getURL() << "has too many vertices" << totalNumVertices << "and will collide as a box.";
|
||||
qWarning() << "model" << "has too many vertices" << totalNumVertices << "and will collide as a box.";
|
||||
shapeInfo.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ QString GooglePolyScriptingInterface::getModelInfo(const QString& input) {
|
|||
}
|
||||
QString urlString(GET_POLY_URL);
|
||||
urlString = urlString.replace("model", name) + "key=" + _authCode;
|
||||
qCDebug(scriptengine) << "Google URL request: " << urlString;
|
||||
qCDebug(scriptengine) << "Google URL request";
|
||||
QUrl url(urlString);
|
||||
QString json = parseJSON(url, 2).toString();
|
||||
return json;
|
||||
|
@ -129,7 +129,7 @@ QUrl GooglePolyScriptingInterface::formatURLQuery(const QString& keyword, const
|
|||
}
|
||||
|
||||
QString GooglePolyScriptingInterface::getModelURL(const QUrl& url) {
|
||||
qCDebug(scriptengine) << "Google URL request: " << url;
|
||||
qCDebug(scriptengine) << "Google URL request";
|
||||
if (!url.isEmpty()) {
|
||||
return parseJSON(url, 1).toString();
|
||||
} else {
|
||||
|
|
|
@ -27,6 +27,9 @@ HMDScriptingInterface::HMDScriptingInterface() {
|
|||
connect(qApp, &Application::activeDisplayPluginChanged, [this]{
|
||||
emit displayModeChanged(isHMDMode());
|
||||
});
|
||||
connect(qApp, &Application::miniTabletEnabledChanged, [this](bool enabled) {
|
||||
emit miniTabletEnabledChanged(enabled);
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec3 HMDScriptingInterface::calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const {
|
||||
|
@ -126,6 +129,15 @@ void HMDScriptingInterface::setShouldShowTablet(bool value) {
|
|||
}
|
||||
}
|
||||
|
||||
void HMDScriptingInterface::setMiniTabletEnabled(bool enabled) {
|
||||
qApp->setMiniTabletEnabled(enabled);
|
||||
}
|
||||
|
||||
bool HMDScriptingInterface::getMiniTabletEnabled() {
|
||||
return qApp->getMiniTabletEnabled();
|
||||
}
|
||||
|
||||
|
||||
QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) {
|
||||
glm::vec3 hudIntersection;
|
||||
auto instance = DependencyManager::get<HMDScriptingInterface>();
|
||||
|
|
|
@ -61,6 +61,8 @@ class QScriptEngine;
|
|||
* @property {Uuid} miniTabletScreenID - The UUID of the mini tablet's screen overlay. <code>null</code> if not in HMD mode.
|
||||
* @property {number} miniTabletHand - The hand that the mini tablet is displayed on: <code>0</code> for left hand,
|
||||
* <code>1</code> for right hand, <code>-1</code> if not in HMD mode.
|
||||
* @property {bool} miniTabletEnabled=true - <code>true</code> if the mini tablet is enabled to be displayed, otherwise
|
||||
* <code>false</code>.
|
||||
* @property {Rect} playArea=0,0,0,0 - The size and position of the HMD play area in sensor coordinates. <em>Read-only.</em>
|
||||
* @property {Vec3[]} sensorPositions=[]] - The positions of the VR system sensors in sensor coordinates. <em>Read-only.</em>
|
||||
*/
|
||||
|
@ -77,6 +79,7 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen
|
|||
Q_PROPERTY(QUuid miniTabletID READ getCurrentMiniTabletID WRITE setCurrentMiniTabletID)
|
||||
Q_PROPERTY(QUuid miniTabletScreenID READ getCurrentMiniTabletScreenID WRITE setCurrentMiniTabletScreenID)
|
||||
Q_PROPERTY(int miniTabletHand READ getCurrentMiniTabletHand WRITE setCurrentMiniTabletHand)
|
||||
Q_PROPERTY(bool miniTabletEnabled READ getMiniTabletEnabled WRITE setMiniTabletEnabled)
|
||||
Q_PROPERTY(QVariant playArea READ getPlayAreaRect);
|
||||
Q_PROPERTY(QVector<glm::vec3> sensorPositions READ getSensorPositions);
|
||||
|
||||
|
@ -355,8 +358,22 @@ signals:
|
|||
*/
|
||||
bool shouldShowHandControllersChanged();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the tablet is shown or hidden.
|
||||
* @function HMD.showTabletChanged
|
||||
* @param {boolean} showTablet - <code>true</code> if the tablet is showing, otherwise <code>false</code>.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void showTabletChanged(bool showTablet);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the ability to display the mini tablet has changed.
|
||||
* @function HMD.miniTabletEnabledChanged
|
||||
* @param {boolean} enabled - <code>true</code> if the mini tablet is enabled to be displayed, otherwise <code>false</code>.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
bool miniTabletEnabledChanged(bool enabled);
|
||||
|
||||
public:
|
||||
HMDScriptingInterface();
|
||||
static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine);
|
||||
|
@ -390,6 +407,9 @@ public:
|
|||
void setCurrentMiniTabletHand(int miniTabletHand) { _miniTabletHand = miniTabletHand; }
|
||||
int getCurrentMiniTabletHand() const { return _miniTabletHand; }
|
||||
|
||||
void setMiniTabletEnabled(bool enabled);
|
||||
bool getMiniTabletEnabled();
|
||||
|
||||
QVariant getPlayAreaRect();
|
||||
QVector<glm::vec3> getSensorPositions();
|
||||
|
||||
|
@ -404,6 +424,7 @@ private:
|
|||
QUuid _miniTabletID;
|
||||
QUuid _miniTabletScreenID;
|
||||
int _miniTabletHand { -1 };
|
||||
bool _miniTabletEnabled { true };
|
||||
|
||||
// Get the position of the HMD
|
||||
glm::vec3 getPosition() const;
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
* <em>Read-only.</em>
|
||||
* @property {number} y - The y display coordinate of the top left corner of the drawable area of the Interface window.
|
||||
* <em>Read-only.</em>
|
||||
* @property {boolean} interstitialModeEnabled=true - <code>true</code> if the interstitial graphics are displayed when the
|
||||
* domain is loading, otherwise <code>false</code>.
|
||||
*/
|
||||
|
||||
class WindowScriptingInterface : public QObject, public Dependency {
|
||||
|
@ -620,9 +622,10 @@ signals:
|
|||
void redirectErrorStateChanged(bool isInErrorState);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when interstitial mode changes.
|
||||
* Triggered when the interstitial mode changes.
|
||||
* @function Window.interstitialModeChanged
|
||||
* @param {bool} interstitialMode - The mode of the interstitial is changed to.
|
||||
* @param {bool} interstitialMode - The new interstitial mode value. If <code>true</code>, the interstitial graphics are
|
||||
* displayed when the domain is loading.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void interstitialModeChanged(bool interstitialMode);
|
||||
|
|