package uk.org.smithfamily.mslogger.activity; import java.util.List; import uk.org.smithfamily.mslogger.ApplicationSettings; import uk.org.smithfamily.mslogger.R; import uk.org.smithfamily.mslogger.dialog.DialogHelper; import uk.org.smithfamily.mslogger.dialog.EditCurveDialog; import uk.org.smithfamily.mslogger.dialog.EditDialog; import uk.org.smithfamily.mslogger.dialog.EditDialog.OnEditDialogResult; import uk.org.smithfamily.mslogger.dialog.EditTableDialog; import uk.org.smithfamily.mslogger.ecuDef.CurveEditor; import uk.org.smithfamily.mslogger.ecuDef.MSDialog; import uk.org.smithfamily.mslogger.ecuDef.Megasquirt; import uk.org.smithfamily.mslogger.ecuDef.Menu; import uk.org.smithfamily.mslogger.ecuDef.SubMenu; import uk.org.smithfamily.mslogger.ecuDef.TableEditor; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; /** * */ public class TuningActivity extends Activity { private LinearLayout firstColumn; private LinearLayout secondColumn; private final String[] EXLUDED_MENUS = new String[] {"Communications","Help"}; private int currentIndexMenu = 0; private Megasquirt ecu; private List<Menu> menus; private Dialog currentDialog; private BroadcastReceiver updateReceiver = new Reciever(); private boolean registered; private boolean powerCycleRequired = false; /** * * @param savedInstanceState */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tuning); setTitle(R.string.tuning); firstColumn = (LinearLayout) findViewById(R.id.firstColumn); secondColumn = (LinearLayout) findViewById(R.id.secondColumn); ecu = ApplicationSettings.INSTANCE.getEcuDefinition(); menus = ecu.getMenusForDialog("main"); // Make the power cycle required text view persistent when activity get destroy // ex: device orientation change if (savedInstanceState != null && savedInstanceState.getBoolean("power_cycle_required")) { powerCycleRequired = true; TextView requiredPowerCycle = (TextView) findViewById(R.id.requiredPowerCycle); requiredPowerCycle.setVisibility(View.VISIBLE); } registerMessages(); drawTuningButtons(); } /** * Save the power cycle required flag when the device is rotated */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean("power_cycle_required", powerCycleRequired); } /** * Register the receiver with the message to receive from the Megasquirt connection */ private void registerMessages() { IntentFilter disconnectedFilter = new IntentFilter(Megasquirt.DISCONNECTED); registerReceiver(updateReceiver, disconnectedFilter); registered = true; } /** * Unregister receiver */ private void deRegisterMessages() { if (registered) { unregisterReceiver(updateReceiver); } } /** * Unregister the events */ @Override protected void onDestroy() { deRegisterMessages(); super.onDestroy(); } /** * Close the currently open dialog so the activity doesn't blow up with an "Activity has leaked window ..." */ @Override public void onPause() { super.onPause(); if (currentDialog != null) { currentDialog.dismiss(); } } /** * Draw the main section of the tuning menus */ private void drawTuningButtons() { Megasquirt ecu = ApplicationSettings.INSTANCE.getEcuDefinition(); final List<Menu> menus = ecu.getMenusForDialog("main"); int nbButtons = 0; for (int i = 0; i < menus.size(); i++) { Menu menu = menus.get(i); String menuLabel = menu.getLabel(); boolean found = false; for (int j = 0; j < EXLUDED_MENUS.length; j++) { if (EXLUDED_MENUS[j].equals(menuLabel)) { found = true; break; } } if (!found) { Button b = new Button(this); b.setText(menuLabel); b.setTag(i); registerForContextMenu(b); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { v.showContextMenu(); } }); if (nbButtons % 2 == 0) { firstColumn.addView(b); } else { secondColumn.addView(b); } nbButtons++; } } } /** * * @param menu * @param v * @param menuInfo */ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); Button b = (Button) v; int indexMenu = Integer.parseInt(b.getTag().toString()); Menu menuDef = menus.get(indexMenu); List<SubMenu> subMenus = menuDef.getSubMenus(); menu.setHeaderTitle(menuDef.getLabel()); currentIndexMenu = indexMenu; // Refresh menu visibility flags ecu.setMenuVisibilityFlags(); for (int i = 0; i < subMenus.size(); i++) { SubMenu subMenu = subMenus.get(i); // Don't display separator if (!subMenu.getName().equals("std_separator")) { menu.add(0, i, 0, subMenu.getLabel()); menu.getItem(menu.size() - 1).setEnabled(ecu.getMenuVisibilityFlagsByName(subMenu.getName())); } } } /** * * @param item */ @Override public boolean onContextItemSelected(MenuItem item) { // Correspond to sub menu index int itemId = item.getItemId(); SubMenu subMenu = menus.get(currentIndexMenu).getSubMenuAt(itemId); String name = subMenu.getName(); TableEditor table = ecu.getTableEditorByName(name); // It's a table! if (table != null) { EditTableDialog tableDialog = new EditTableDialog(TuningActivity.this, table); tableDialog.show(); this.currentDialog = tableDialog; } else { // Refresh user defined flags ecu.setUserDefinedVisibilityFlags(); CurveEditor curve = ecu.getCurveEditorByName(name); // It's a curve! if (curve != null) { EditCurveDialog curveDialog = new EditCurveDialog(TuningActivity.this, curve); curveDialog.show(); this.currentDialog = curveDialog; } else { MSDialog dialog = ecu.getDialogByName(name); // It's a dialog! if (dialog != null) { EditDialog editDialog = new EditDialog(TuningActivity.this, dialog); editDialog.setDialogResult(new OnEditDialogResult() { public void finish(boolean isPowerCycle) { // Show power cycle required if needed if (isPowerCycle) { TextView requiredPowerCycle = (TextView) findViewById(R.id.requiredPowerCycle); requiredPowerCycle.setVisibility(View.VISIBLE); powerCycleRequired = true;; } } }); editDialog.show(); this.currentDialog = editDialog; } else { // Not a regular dialog, but maybe it's an std_* dialog dialog = DialogHelper.getStdDialog(name); if (dialog != null) { EditDialog editDialog = new EditDialog(TuningActivity.this, dialog); editDialog.show(); this.currentDialog = editDialog; } else { Dialog customDialog = DialogHelper.getStdCustomDialog(TuningActivity.this, name); if (customDialog != null) { customDialog.show(); this.currentDialog = customDialog; } // No idea what it is, we're screwed! else { AlertDialog.Builder builder = new AlertDialog.Builder(TuningActivity.this); builder.setMessage("Sorry, \"" + name + "\" is not currently supported.") .setIcon(android.R.drawable.ic_dialog_info) .setTitle("Unsupported") .setCancelable(true) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) {} }); AlertDialog alert = builder.create(); alert.show(); } } } } } return true; } /** * Receiver that get events from other activities about Megasquirt status and activities */ private final class Reciever extends BroadcastReceiver { /** * When an event is received * * @param context * @param intent */ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Megasquirt.DISCONNECTED)) { powerCycleRequired = false; // Make sure power cycle required text view is gone when MegaSquirt get disconnected TextView requiredPowerCycle = (TextView) findViewById(R.id.requiredPowerCycle); requiredPowerCycle.setVisibility(View.GONE); } } } }