/**
* Wire
* Copyright (C) 2016 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.waz.zclient.controllers.globallayout;
import android.app.Activity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import com.waz.zclient.controllers.navigation.Page;
import com.waz.zclient.utils.ViewUtils;
import com.waz.zclient.utils.keyboard.KeyboardVisibilityListener;
import java.util.HashSet;
import java.util.Set;
public class GlobalLayoutController implements IGlobalLayoutController {
public static final String TAG = GlobalLayoutController.class.getName();
protected Set<GlobalLayoutObserver> globalLayoutObservers = new HashSet<>();
protected Set<KeyboardVisibilityObserver> keyboardVisibilityObservers = new HashSet<>();
protected Set<KeyboardHeightObserver> keyboardHeightObservers = new HashSet<>();
protected Set<StatusBarVisibilityObserver> statusBarVisibilityObservers = new HashSet<>();
private View globalLayout;
private Activity activity;
private ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener;
private KeyboardVisibilityListener keyboardListener;
private KeyboardVisibilityListener.Callback keyboardCallback = new KeyboardVisibilityListener.Callback() {
@Override
public void onKeyboardChanged(boolean keyboardIsVisible, int keyboardHeight) {
notifyKeyboardVisibilityHasChanged(keyboardIsVisible, keyboardHeight);
}
@Override
public void onKeyboardHeightChanged(int keyboardHeight) {
notifyKeyboardHeightHasChanged(keyboardHeight);
}
};
public GlobalLayoutController() {
globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
notifyGlobalLayoutHasChanged();
keyboardListener.onLayoutChange();
}
};
}
@Override
public void setActivity(Activity activity) {
this.activity = activity;
}
@Override
public void setGlobalLayout(View view) {
if (globalLayout != null) {
globalLayout.getViewTreeObserver().removeOnGlobalLayoutListener(globalLayoutListener);
keyboardListener.setCallback(null);
keyboardListener = null;
}
globalLayout = view;
// Listen to layout changes to determine when keyboard becomes visible / hidden
keyboardListener = new KeyboardVisibilityListener(view);
keyboardListener.setCallback(keyboardCallback);
globalLayout.getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener);
}
@Override
public void keepScreenAwake() {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void resetScreenAwakeState() {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void tearDown() {
if (globalLayout != null) {
this.globalLayout.getViewTreeObserver().removeOnGlobalLayoutListener(globalLayoutListener);
globalLayout = null;
}
activity = null;
keyboardListener = null;
}
@Override
public void addGlobalLayoutObserver(GlobalLayoutObserver globalLayoutObserver) {
globalLayoutObservers.add(globalLayoutObserver);
}
@Override
public void removeGlobalLayoutObserver(GlobalLayoutObserver globalLayoutObserver) {
globalLayoutObservers.remove(globalLayoutObserver);
}
protected void notifyGlobalLayoutHasChanged() {
for (GlobalLayoutObserver globalLayoutObserver : globalLayoutObservers) {
globalLayoutObserver.onGlobalLayoutChanged();
}
}
@Override
public void addKeyboardVisibilityObserver(KeyboardVisibilityObserver keyboardVisibilityObserver) {
keyboardVisibilityObservers.add(keyboardVisibilityObserver);
}
@Override
public void removeKeyboardVisibilityObserver(KeyboardVisibilityObserver keyboardVisibilityObserver) {
keyboardVisibilityObservers.remove(keyboardVisibilityObserver);
}
protected void notifyKeyboardVisibilityHasChanged(boolean keyboardIsVisible, int keyboardHeight) {
for (KeyboardVisibilityObserver keyboardVisibilityObserver : keyboardVisibilityObservers) {
keyboardVisibilityObserver.onKeyboardVisibilityChanged(keyboardIsVisible, keyboardHeight, activity.getCurrentFocus());
}
}
@Override
public void addKeyboardHeightObserver(KeyboardHeightObserver keyboardHeightObserver) {
keyboardHeightObservers.add(keyboardHeightObserver);
}
@Override
public void removeKeyboardHeightObserver(KeyboardHeightObserver keyboardHeightObserver) {
keyboardHeightObservers.remove(keyboardHeightObserver);
}
@Override
public void setSoftInputModeForPage(Page page) {
if (activity == null ||
activity.getWindow() == null) {
return;
}
ViewUtils.setSoftInputMode(activity.getWindow(),
getSoftInputModeForPage(page),
TAG);
}
@Override
public int getSoftInputModeForPage(Page page) {
int softInputMode;
switch (page) {
case SEND_CONNECT_REQUEST:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
break;
case START:
case EMAIL_LOGIN:
case PHONE_LOGIN:
case MESSAGE_STREAM:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
break;
case ARCHIVE:
case CONVERSATION_LIST:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
break;
case PARTICIPANT:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
break;
case PICK_USER:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
break;
case PHONE_REGISTRATION:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
break;
case DRAWING:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
break;
case COLLECTION:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
break;
default:
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
}
return softInputMode;
}
@Override
public void addStatusBarVisibilityObserver(StatusBarVisibilityObserver observer) {
statusBarVisibilityObservers.add(observer);
}
@Override
public void removeStatusBarVisibilityObserver(StatusBarVisibilityObserver observer) {
statusBarVisibilityObservers.remove(observer);
}
@Override
public void showStatusBar(Activity activity) {
if (activity == null) {
return;
}
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
for (StatusBarVisibilityObserver observer : statusBarVisibilityObservers) {
observer.onStatusBarVisibilityChanged(true);
}
}
@Override
public void hideStatusBar(Activity activity) {
if (activity == null) {
return;
}
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
for (StatusBarVisibilityObserver observer : statusBarVisibilityObservers) {
observer.onStatusBarVisibilityChanged(false);
}
}
@Override
public boolean isKeyboardVisible() {
if (keyboardListener == null) {
return false;
}
return keyboardListener.getKeyboardHeight() > 0;
}
protected void notifyKeyboardHeightHasChanged(int keyboardHeight) {
for (KeyboardHeightObserver keyboardHeightObserver : keyboardHeightObservers) {
keyboardHeightObserver.onKeyboardHeightChanged(keyboardHeight);
}
}
}