package com.lateensoft.pathfinder.toolkit; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; import android.app.ActionBar; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.*; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.ExpandableListView.OnGroupClickListener; import android.widget.ExpandableListView.OnGroupCollapseListener; import android.widget.ExpandableListView.OnGroupExpandListener; import android.widget.ImageView; import android.widget.RelativeLayout; import com.google.common.collect.Lists; import com.lateensoft.pathfinder.toolkit.adapters.nav.NavDrawerAdapter; import com.lateensoft.pathfinder.toolkit.adapters.nav.NavDrawerChildItem; import com.lateensoft.pathfinder.toolkit.adapters.nav.NavDrawerGroupItem; import com.lateensoft.pathfinder.toolkit.adapters.nav.NavDrawerItem; import com.lateensoft.pathfinder.toolkit.patching.UpdatePatcher; import com.lateensoft.pathfinder.toolkit.patching.UpdatePatcher.PatcherListener; import com.lateensoft.pathfinder.toolkit.patching.UpdatePatcher.PatcherTask; import com.lateensoft.pathfinder.toolkit.util.InputMethodUtils; import com.lateensoft.pathfinder.toolkit.views.*; import com.lateensoft.pathfinder.toolkit.views.character.*; import com.lateensoft.pathfinder.toolkit.views.character.CharacterSkillsFragment; import com.lateensoft.pathfinder.toolkit.views.encounter.EncounterFragment; import com.lateensoft.pathfinder.toolkit.views.party.PartyManagerFragment; import com.lateensoft.pathfinder.toolkit.views.settings.SettingsActivity; import org.jetbrains.annotations.NotNull; import roboguice.activity.RoboFragmentActivity; public class MainActivity extends RoboFragmentActivity implements OnChildClickListener, OnGroupClickListener, OnGroupExpandListener, OnGroupCollapseListener { private static final String TAG = MainActivity.class.getSimpleName(); private static final String KEY_CURRENT_FRAGMENT = "fragment_class_name"; private DrawerLayout m_drawerLayout; private RelativeLayout m_leftDrawer; private ExpandableListView m_drawerList; private BasePageFragment m_currentFragment; private Deque<Class<? extends BasePageFragment>> m_fragmentBackStack; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); m_fragmentBackStack = new ArrayDeque<Class<? extends BasePageFragment>>(); setContentView(R.layout.activity_drawer_main); setupNavDrawer(); getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); // Patching UpdatePatcher patcher = new UpdatePatcher(this); if (patcher.isPatchRequired()) { final ProgressDialog progDialog = new ProgressDialog(this); progDialog.setCancelable(false); progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progDialog.setTitle(getString(R.string.updating_dialog_message)); progDialog.show(); PatcherTask task = new PatcherTask(patcher); PatcherListener patchListener = new PatcherListener() { @Override public void onPatchComplete(boolean completeSuccess) { progDialog.dismiss(); MainActivity.this.showStartupFragment(savedInstanceState); } }; task.execute(patchListener); } else { showStartupFragment(savedInstanceState); } showRateDialogIfRequired(); } @Override protected void onSaveInstanceState(Bundle outState) { outState.putString(KEY_CURRENT_FRAGMENT, m_currentFragment.getSupportClass().getCanonicalName()); super.onSaveInstanceState(outState); } private void showStartupFragment(Bundle savedInstanceState) { String fragmentName = savedInstanceState != null ? savedInstanceState.getString(KEY_CURRENT_FRAGMENT) : null; Class<? extends BasePageFragment> fragmentClass = null; if (fragmentName != null) { fragmentClass = toPageFragmentClass(fragmentName); } if (fragmentClass == null) { fragmentClass = CharacterFluffFragment.class; } showFragment(fragmentClass); } @SuppressWarnings("unchecked") private Class<? extends BasePageFragment> toPageFragmentClass(final String className){ try{ return (Class<? extends BasePageFragment>) Class.forName(className); } catch(Exception e){ throw new IllegalStateException(e); } } private void setupNavDrawer() { m_drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); m_drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); m_leftDrawer = (RelativeLayout) findViewById(R.id.left_drawer); ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, /* host Activity */ m_drawerLayout, /* DrawerLayout object */ R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */ R.string.app_name, /* "open drawer" description */ R.string.app_name /* "close drawer" description */ ) { /** Called when a drawer has settled in a completely closed state. */ public void onDrawerClosed(View view) { if (m_currentFragment != null) { m_currentFragment.updateTitle(); } invalidateOptionsMenu(); } /** Called when a drawer has settled in a completely open state. */ public void onDrawerOpened(View drawerView) { ActionBar ab = getActionBar(); if (ab != null) { ab.setTitle(R.string.app_name); ab.setSubtitle(null); } invalidateOptionsMenu(); InputMethodUtils.hideSoftKeyboard(MainActivity.this); } }; drawerToggle.syncState(); m_drawerLayout.setDrawerListener(drawerToggle); m_drawerList = (ExpandableListView) findViewById(R.id.drawer_exp_lv); // Set the adapter for the list view m_drawerList.setAdapter(new NavDrawerAdapter(this, buildNavDrawerList())); m_drawerList.setGroupIndicator(getResources().getDrawable(R.drawable.nav_item_expand_icon)); // Set the list's click listener m_drawerList.setOnChildClickListener(this); m_drawerList.setOnGroupClickListener(this); m_drawerList.setOnGroupExpandListener(this); m_drawerList.setOnGroupCollapseListener(this); ImageView settingsButton = (ImageView) findViewById(R.id.iv_settings_button); settingsButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, SettingsActivity.class)); } }); } private void showRateDialogIfRequired() { RateDialogHelper rateHelper = new RateDialogHelper(this); if (rateHelper.shouldPromptToRate()) { rateHelper.buildAndShowDialog(); } } @Override public boolean onPrepareOptionsMenu(Menu menu) { boolean drawerOpen = isDrawerOpen(); for (int i = 0; i < menu.size(); i++) { menu.getItem(i).setVisible(!drawerOpen); } return super.onPrepareOptionsMenu(menu); } public boolean isDrawerOpen() { return m_drawerLayout.isDrawerOpen(m_leftDrawer); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { setDrawerOpen(!isDrawerOpen()); } return super.onOptionsItemSelected(item); } @Override public void onBackPressed() { if (m_fragmentBackStack.size() > 0) { showFragment(m_fragmentBackStack.pop(), false); } else { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.confirm_exit_dialog_title) .setMessage(R.string.confirm_exit_dialog_message) .setPositiveButton(R.string.ok_button_text, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }) .setNegativeButton(R.string.cancel_button_text, null) .show(); } } private void showFragmentForNavItem(NavDrawerItem item) { showFragmentForNavItem(item, true); } private void showFragmentForNavItem(NavDrawerItem item, boolean pushCurrentToStack) { NavDrawerAdapter adapter = (NavDrawerAdapter) m_drawerList.getExpandableListAdapter(); if (adapter != null && item != null) { Class<? extends BasePageFragment> fragmentClass = item.getFragmentClass(); if (fragmentClass == null) return; try { adapter.setSelectedItem(item); showFragment(fragmentClass.newInstance(), pushCurrentToStack); m_drawerList.invalidateViews(); if (item instanceof NavDrawerChildItem) { int groupIndex = adapter.getGroupIndexForItem(item); if (groupIndex >= 0) { m_drawerList.expandGroup(groupIndex); } } } catch (InstantiationException e) { Log.e(TAG, null, e); } catch (IllegalAccessException e) { Log.e(TAG, null, e); } } } public void showFragment(@NotNull Class<? extends BasePageFragment> fragmentClass) { showFragment(fragmentClass, true); } public void showFragment(@NotNull Class<? extends BasePageFragment> fragmentClass, boolean pushCurrentToStack) { NavDrawerAdapter adapter = ((NavDrawerAdapter) m_drawerList.getExpandableListAdapter()); if (adapter == null) return; NavDrawerItem item = adapter.getItemForFragment(fragmentClass); if (item != null) { showFragmentForNavItem(item, pushCurrentToStack); } else { Log.e(TAG, "Cannot show " + fragmentClass); } } private void showFragment(BasePageFragment fragment, boolean pushCurrentToStack) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.content_frame, fragment); fragmentTransaction.commit(); if (m_currentFragment != null && pushCurrentToStack) { m_fragmentBackStack.push(m_currentFragment.getSupportClass()); } m_currentFragment = fragment; } @Override public void onGroupCollapse(int arg0) { // Do nothing } @Override public void onGroupExpand(int arg0) { // Do nothing } @Override public boolean onGroupClick(ExpandableListView list, View parent, int groupPosition, long id){ NavDrawerAdapter adapter = (NavDrawerAdapter) list.getExpandableListAdapter(); if (adapter != null) { NavDrawerGroupItem group = (NavDrawerGroupItem) adapter.getGroup(groupPosition); if (group != null && group.getChildren() == null && group != adapter.getSelectedItem()) { // Group is selectable, and was not selected showFragmentForNavItem(group); setDrawerOpen(false); } } return false; } @Override public boolean onChildClick(ExpandableListView list, View parent, int groupPosition, int childPosition, long id) { NavDrawerAdapter adapter = (NavDrawerAdapter) list.getExpandableListAdapter(); if (adapter != null) { NavDrawerChildItem child = (NavDrawerChildItem) adapter.getChild(groupPosition, childPosition); if (child != adapter.getSelectedItem()) { showFragmentForNavItem(child); } } setDrawerOpen(false); return false; } private void setDrawerOpen(boolean open) { if (open) { m_drawerLayout.openDrawer(m_leftDrawer); } else { m_drawerLayout.closeDrawer(m_leftDrawer); } } private List<NavDrawerGroupItem> buildNavDrawerList() { List<NavDrawerChildItem> characterPages = Lists.newArrayList( createCharacterSheetItem(R.string.tab_character_fluff, CharacterFluffFragment.class), createCharacterSheetItem(R.string.tab_character_combat_stats, CharacterCombatStatsFragment.class), createCharacterSheetItem(R.string.tab_character_abilities, CharacterAbilitiesFragment.class), createCharacterSheetItem(R.string.tab_character_skills, CharacterSkillsFragment.class), createCharacterSheetItem(R.string.tab_character_inventory, CharacterInventoryFragment.class), createCharacterSheetItem(R.string.tab_character_armor, CharacterArmorFragment.class), createCharacterSheetItem(R.string.tab_character_weapons, CharacterWeaponsFragment.class), createCharacterSheetItem(R.string.tab_character_feats, CharacterFeatsFragment.class), createCharacterSheetItem(R.string.tab_character_spells, CharacterSpellBookFragment.class), createCharacterSheetItem(R.string.tab_character_membership, CharacterPartyMembershipFragment.class) ); return Lists.newArrayList( new NavDrawerGroupItem(getString(R.string.main_menu_character_group), R.drawable.character_sheet_icon, characterPages), new NavDrawerGroupItem(getString(R.string.main_menu_encounters), R.drawable.initiative_icon, EncounterFragment.class), new NavDrawerGroupItem(getString(R.string.main_menu_party_manager), R.drawable.party_icon, PartyManagerFragment.class), new NavDrawerGroupItem(getString(R.string.main_menu_pointbuy), R.drawable.stat_calc_icon, PointbuyCalculatorFragment.class), new NavDrawerGroupItem(getString(R.string.main_menu_dice_roller), R.drawable.dice_roller_icon, DiceRollerFragment.class) ); } private NavDrawerChildItem createCharacterSheetItem(int textId, Class<? extends AbstractCharacterSheetFragment> fragment) { NavDrawerChildItem item = new NavDrawerChildItem(getString(textId), R.drawable.character_sheet_icon, fragment); item.setIconVisibility(View.INVISIBLE); return item; } public void hideKeyboardDelayed(long delayMs) { new Handler().postDelayed(new Runnable() { @Override public void run() { InputMethodUtils.hideSoftKeyboard(MainActivity.this); } }, delayMs); } }