package org.droidplanner.android.activities;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.google.android.gms.maps.GoogleMap;
import org.droidplanner.android.R;
import org.droidplanner.android.activities.helpers.SuperUI;
import org.droidplanner.android.fragments.SettingsFragment;
import org.droidplanner.android.fragments.actionbar.ActionBarTelemFragment;
import org.droidplanner.android.maps.providers.google_map.GoogleMapFragment;
import org.droidplanner.android.widgets.SlidingDrawer;
/**
* This abstract activity provides its children access to a navigation drawer
* interface.
*/
public abstract class DrawerNavigationUI extends SuperUI implements SlidingDrawer.OnDrawerOpenListener, SlidingDrawer.OnDrawerCloseListener {
private static final String TAG = DrawerNavigationUI.class.getSimpleName();
/**
* Activates the navigation drawer when the home button is clicked.
*/
private ActionBarDrawerToggle mDrawerToggle;
/**
* Navigation drawer used to access the different sections of the app.
*/
private DrawerLayout mDrawerLayout;
private SlidingDrawer actionDrawer;
/**
* Container for the activity content.
*/
private FrameLayout contentLayout;
private NavDrawerViewHolder mNavViewsHolder;
/**
* Clicking on an entry in the open navigation drawer updates this intent.
* When the navigation drawer closes, the intent is used to navigate to the desired location.
*/
private Intent mNavigationIntent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve the drawer layout container.
mDrawerLayout = (DrawerLayout) getLayoutInflater().inflate(R.layout.activity_drawer_navigation_ui, null);
contentLayout = (FrameLayout) mDrawerLayout.findViewById(R.id.content_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerClosed(View drawerView) {
switch (drawerView.getId()) {
case R.id.navigation_drawer_container:
if (mNavigationIntent != null) {
startActivity(mNavigationIntent);
mNavigationIntent = null;
}
break;
}
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
actionDrawer = (SlidingDrawer) mDrawerLayout.findViewById(R.id.action_drawer_container);
actionDrawer.setOnDrawerCloseListener(this);
actionDrawer.setOnDrawerOpenListener(this);
}
protected View getActionDrawer() {
return actionDrawer;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
switch(requestCode) {
case GoogleMapFragment.REQUEST_CHECK_SETTINGS:
LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(new Intent(SettingsFragment.ACTION_LOCATION_SETTINGS_UPDATED)
.putExtra(SettingsFragment.EXTRA_RESULT_CODE, resultCode));
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
/**
* Intercepts the call to 'setContentView', and wrap the passed layout
* within a DrawerLayout object. This way, the children of this class don't
* have to do anything to benefit from the navigation drawer.
*
* @param layoutResID layout resource for the activity view
*/
@Override
public void setContentView(int layoutResID) {
final View contentView = getLayoutInflater().inflate(layoutResID, mDrawerLayout, false);
contentLayout.addView(contentView);
setContentView(mDrawerLayout);
initToolbar();
initNavigationDrawer();
}
private void initToolbar() {
final int toolbarId = getToolbarId();
final Toolbar toolbar = (Toolbar) findViewById(toolbarId);
toolbar.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
final float topMargin = getActionDrawerTopMargin();
final int fullTopMargin = (int) (topMargin + (bottom - top));
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) actionDrawer.getLayoutParams();
if(lp.topMargin != fullTopMargin) {
lp.topMargin = fullTopMargin;
actionDrawer.requestLayout();
}
}
});
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
}
final FragmentManager fm = getSupportFragmentManager();
Fragment actionBarTelem = fm.findFragmentById(toolbarId);
if (actionBarTelem == null) {
actionBarTelem = new ActionBarTelemFragment();
fm.beginTransaction().add(toolbarId, actionBarTelem).commit();
}
}
protected float getActionDrawerTopMargin() {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (mDrawerToggle != null)
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
if (mDrawerToggle != null) {
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
}
@Override
public void onResume() {
super.onResume();
updateNavigationDrawer();
}
/**
* Initializes the navigation drawer.
*/
private void initNavigationDrawer() {
final View containerView = findViewById(R.id.navigation_drawer_container);
if (containerView != null) {
mNavViewsHolder = new NavDrawerViewHolder(containerView);
}
}
private void updateNavigationDrawer() {
if (mNavViewsHolder == null) {
return;
}
final Context context = getApplicationContext();
final int navDrawerEntryId = getNavigationDrawerEntryId();
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mAccount, new Intent(context, AccountActivity.class));
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mFlightData, new Intent(context, FlightActivity.class));
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mEditor, new Intent(context, EditorActivity.class));
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mLocator, new Intent(context, LocatorActivity.class));
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mSettings, new Intent(context, SettingsActivity.class));
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mCalibration, new Intent(context,
ConfigurationActivity.class).putExtra(ConfigurationActivity
.EXTRA_CONFIG_SCREEN_ID, R.id.navigation_calibration));
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mChecklist, new Intent(context,
ConfigurationActivity.class).putExtra(ConfigurationActivity
.EXTRA_CONFIG_SCREEN_ID, R.id.navigation_checklist));
setupNavigationEntry(navDrawerEntryId, mNavViewsHolder.mParams, new Intent(context,
ConfigurationActivity.class).putExtra(ConfigurationActivity
.EXTRA_CONFIG_SCREEN_ID, R.id.navigation_params));
}
private void setupNavigationEntry(int currentEntryId, TextView navView, final Intent clickIntent) {
if (navView == null) {
return;
}
if (currentEntryId == navView.getId()) {
//Bold the entry label
navView.setTypeface(null, Typeface.BOLD);
navView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDrawerLayout.closeDrawer(Gravity.START);
}
});
} else {
navView.setTypeface(null, Typeface.NORMAL);
navView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (clickIntent != null) {
mNavigationIntent = clickIntent;
}
mDrawerLayout.closeDrawer(Gravity.START);
}
});
}
}
protected abstract int getToolbarId();
protected boolean isActionDrawerOpened() {
return actionDrawer.isOpened();
}
protected int getActionDrawerId() {
return R.id.action_drawer_content;
}
/**
* Called when the action drawer is opened.
* Should be override by children as needed.
*/
@Override
public void onDrawerOpened() {
}
/**
* Called when the action drawer is closed.
* Should be override by children as needed.
*/
@Override
public void onDrawerClosed() {
}
protected void openActionDrawer() {
actionDrawer.animateOpen();
actionDrawer.lock();
}
protected void closeActionDrawer() {
actionDrawer.animateClose();
actionDrawer.lock();
}
protected abstract int getNavigationDrawerEntryId();
/**
* Holder class for the navigation entry views in the navigation drawer.
* They are stored here to avoid re-instantiating through 'findViewById' which can be a bit
* costly.
*/
private static class NavDrawerViewHolder {
final TextView mAccount;
final TextView mFlightData;
final TextView mEditor;
final TextView mLocator;
final TextView mSettings;
final TextView mParams;
final TextView mChecklist;
final TextView mCalibration;
private NavDrawerViewHolder(View containerView) {
mAccount = (TextView) containerView.findViewById(R.id.navigation_account);
mFlightData = (TextView) containerView.findViewById(R.id.navigation_flight_data);
mEditor = (TextView) containerView.findViewById(R.id.navigation_editor);
mLocator = (TextView) containerView.findViewById(R.id.navigation_locator);
mSettings = (TextView) containerView.findViewById(R.id.navigation_settings);
mParams = (TextView) containerView.findViewById(R.id.navigation_params);
mChecklist = (TextView) containerView.findViewById(R.id.navigation_checklist);
mCalibration = (TextView) containerView.findViewById(R.id.navigation_calibration);
}
}
}