package view_inspector.ui;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import com.f2prateek.rx.preferences.Preference;
import javax.inject.Inject;
import view_inspector.R;
import view_inspector.ViewInspector;
import view_inspector.dagger.qualifier.BypassInterceptor;
import view_inspector.dagger.scope.PerActivity;
import view_inspector.profile.ProfileUtil;
import view_inspector.ui.dialog.BaseDialog;
import view_inspector.ui.dialog.ProfileResultDialog;
import view_inspector.ui.menu.BaseMenu;
import view_inspector.ui.menu.BoundaryMenu;
import view_inspector.ui.menu.EventMenu;
import view_inspector.ui.menu.LayerMenu;
import view_inspector.ui.menu.SettingsMenu;
import static android.graphics.PixelFormat.TRANSLUCENT;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
@PerActivity public class ViewInspectorToolbar extends FrameLayout
implements ProfileUtil.ProfileResultListener {
private static final int TOOLBAR_MENU_ITEMS = 5;
private final Context mContext;
private final int mToolbarWidth;
private final int mToolbarClosedWidth;
@Inject @BypassInterceptor Preference<Boolean> bypassInterceptor;
@Inject ProfileUtil profileUtil;
@Inject WindowManager windowManager;
@Inject ProfileProgressbar profileProgressbar;
private View mToolbar;
private ImageButton mToggleButton;
private BaseMenu mMenu;
@Inject public ViewInspectorToolbar(Context context) {
super(context);
ViewInspector.runtimeComponentMap.get(context).inject(this);
mContext = context;
inflate(context, R.layout.view_inspector_toolbar, this);
Resources resources = mContext.getResources();
mToolbarWidth = resources.getDimensionPixelSize(R.dimen.view_inspector_toolbar_header_width)
+ resources.getDimensionPixelSize(R.dimen.view_inspector_toolbar_icon_width)
* TOOLBAR_MENU_ITEMS;
mToolbarClosedWidth =
resources.getDimensionPixelSize(R.dimen.view_inspector_toolbar_closed_width);
}
public static WindowManager.LayoutParams createLayoutParams(Context context) {
Resources res = context.getResources();
int width = res.getDimensionPixelSize(R.dimen.view_inspector_toolbar_header_width)
+ res.getDimensionPixelSize(R.dimen.view_inspector_toolbar_icon_width) * TOOLBAR_MENU_ITEMS;
int height = res.getDimensionPixelSize(R.dimen.view_inspector_toolbar_height);
if (Build.VERSION.SDK_INT == 23) { // MARSHMALLOW
height = res.getDimensionPixelSize(R.dimen.view_inspector_toolbar_height_m);
}
final WindowManager.LayoutParams params =
new WindowManager.LayoutParams(width, height, TYPE_SYSTEM_ERROR,
FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_NO_LIMITS
| FLAG_LAYOUT_INSET_DECOR | FLAG_LAYOUT_IN_SCREEN, TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.RIGHT;
return params;
}
@Override protected void onAttachedToWindow() {
super.onAttachedToWindow();
mToolbar = findViewById(R.id.toolbar);
mToggleButton = (ImageButton) findViewById(R.id.toggle_menu);
ImageButton buttonBoundaryMenu = (ImageButton) findViewById(R.id.outline_menu);
ImageButton buttonLayerMenu = (ImageButton) findViewById(R.id.layer_menu);
ImageButton buttonEventMenu = (ImageButton) findViewById(R.id.event_menu);
ImageButton buttonSettingsMenu = (ImageButton) findViewById(R.id.settings_menu);
mToolbar.setTranslationX(mToolbarWidth);
ObjectAnimator animator = ObjectAnimator.ofFloat(mToolbar, "translationX", mToolbarWidth,
mToolbarWidth - mToolbarClosedWidth);
animator.setInterpolator(new DecelerateInterpolator());
animator.start();
mToggleButton.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
closeMenu();
toggleToolbar();
}
});
buttonBoundaryMenu.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
if (!(mMenu instanceof BoundaryMenu)) {
closeMenu();
mMenu = new BoundaryMenu(mContext);
windowManager.addView(mMenu, BaseMenu.createLayoutParams(mContext));
} else {
closeMenu();
}
}
});
buttonLayerMenu.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
if (!(mMenu instanceof LayerMenu)) {
closeMenu();
mMenu = new LayerMenu(mContext);
windowManager.addView(mMenu, BaseMenu.createLayoutParams(mContext));
} else {
closeMenu();
}
}
});
buttonEventMenu.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
if (!(mMenu instanceof EventMenu)) {
closeMenu();
mMenu = new EventMenu(mContext);
windowManager.addView(mMenu, BaseMenu.createLayoutParams(mContext));
} else {
closeMenu();
}
}
});
buttonSettingsMenu.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
if (!(mMenu instanceof SettingsMenu)) {
closeMenu();
mMenu = new SettingsMenu(mContext);
windowManager.addView(mMenu, BaseMenu.createLayoutParams(mContext));
} else {
closeMenu();
}
}
});
}
@Override protected void onDetachedFromWindow() {
closeMenu();
super.onDetachedFromWindow();
}
public void closeMenu() {
if (mMenu != null) {
windowManager.removeViewImmediate(mMenu);
mMenu = null;
}
}
public BaseMenu getMenu() {
return mMenu;
}
public void openMenu(BaseMenu baseMenu) {
mMenu = baseMenu;
windowManager.addView(mMenu, BaseMenu.createLayoutParams(mContext));
}
@SuppressWarnings("deprecation") public void toggleToolbar() {
ObjectAnimator animator =
ObjectAnimator.ofFloat(mToolbar, "translationX", mToolbar.getTranslationX(),
mToolbar.getTranslationX() < mToolbarClosedWidth ? mToolbarWidth - mToolbarClosedWidth
: 0);
animator.setInterpolator(new DecelerateInterpolator());
animator.start();
if (mToolbar.getTranslationX() < mToolbarClosedWidth) {
mToggleButton.setImageDrawable(
getResources().getDrawable(R.drawable.ic_chevron_left_white_24dp));
} else {
mToggleButton.setImageDrawable(
getResources().getDrawable(R.drawable.ic_chevron_right_white_24dp));
}
}
@SuppressWarnings("deprecation") public void closeToolbar() {
closeMenu();
ObjectAnimator animator =
ObjectAnimator.ofFloat(mToolbar, "translationX", mToolbar.getTranslationX(), mToolbarWidth);
animator.setInterpolator(new DecelerateInterpolator());
animator.start();
mToggleButton.setImageDrawable(
getResources().getDrawable(R.drawable.ic_chevron_left_white_24dp));
}
@Override public void onProfileDone() {
((Activity) mContext).runOnUiThread(new Runnable() {
@Override public void run() {
new ProfileResultDialog(
new ContextThemeWrapper(mContext, BaseDialog.getDialogTheme(mContext)),
profileProgressbar.getSamples()).show();
closeProgressbar();
}
});
}
@Override public void onProgress(final int step) {
((Activity) mContext).runOnUiThread(new Runnable() {
@Override public void run() {
profileProgressbar.setProgress(step);
}
});
}
public void showProgressbar() {
windowManager.addView(profileProgressbar, ProfileProgressbar.createLayoutParams(mContext));
// lock screen orientation
int currentOrientation = mContext.getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
((Activity) mContext).setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else {
((Activity) mContext).setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
}
private void closeProgressbar() {
windowManager.removeViewImmediate(profileProgressbar);
// unlock screen orientation
((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}