package uk.org.smithfamily.mslogger.dialog; import java.util.*; import java.util.Map.Entry; import uk.org.smithfamily.mslogger.DataManager; import uk.org.smithfamily.mslogger.R; import uk.org.smithfamily.mslogger.ecuDef.OutputChannel; import uk.org.smithfamily.mslogger.log.DebugLogManager; import uk.org.smithfamily.mslogger.widgets.*; import uk.org.smithfamily.mslogger.widgets.Indicator.DisplayType; import uk.org.smithfamily.mslogger.widgets.Indicator.Orientation; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.*; import android.widget.AdapterView.OnItemSelectedListener; /** * Dialog to change various gauge settings */ public class EditIndicatorDialog extends Dialog implements android.view.View.OnClickListener { private final Indicator indicator; private final Map<String, String[]> channels = new HashMap<String, String[]>(); private OnEditIndicatorResult mDialogResult; /** * * @param context * @param indicator */ public EditIndicatorDialog(final Context context, final Indicator indicator) { super(context); this.indicator = indicator; } /** * Called when the dialog is first created to initialise some value * * @param savedInstanceState */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.editindicator); setTitle(R.string.edit_indicator_title); populateFields(); prepareChannelSpinner(); prepareOrientationSpinner(); prepareTypeSpinner(); final Button buttonOK = (Button) findViewById(R.id.editOK); final Button buttonReset = (Button) findViewById(R.id.editReset); final Button buttonRemove = (Button) findViewById(R.id.editRemove); buttonOK.setOnClickListener(this); buttonReset.setOnClickListener(this); buttonRemove.setOnClickListener(this); } /** * Fill up all the indicator details fields * * @param gd GaugeDetails to populate the fields with */ private void populateFields() { setValue(R.id.editTitle, indicator.getTitle()); setValue(R.id.editUnits, indicator.getUnits()); setValue(R.id.editHi, Double.toString(indicator.getMax())); setValue(R.id.editLo, Double.toString(indicator.getMin())); setValue(R.id.editHiD, Double.toString(indicator.getHiD())); setValue(R.id.editHiW, Double.toString(indicator.getHiW())); setValue(R.id.editLoD, Double.toString(indicator.getLowD())); setValue(R.id.editLoW, Double.toString(indicator.getLowW())); setValue(R.id.editVD, Integer.toString(indicator.getVd())); setValue(R.id.editLD, Integer.toString(indicator.getLd())); setValue(R.id.editoffsetAngle, Double.toString(indicator.getOffsetAngle())); } private void populateFields(final IndicatorDefault id) { setValue(R.id.editTitle, id.getTitle()); setValue(R.id.editUnits, id.getUnits()); setValue(R.id.editHi, Double.toString(id.getMax())); setValue(R.id.editLo, Double.toString(id.getMin())); setValue(R.id.editHiD, Double.toString(id.getHiD())); setValue(R.id.editHiW, Double.toString(id.getHiW())); setValue(R.id.editLoD, Double.toString(id.getLoD())); setValue(R.id.editLoW, Double.toString(id.getLoW())); setValue(R.id.editVD, Integer.toString(id.getVd())); setValue(R.id.editLD, Integer.toString(id.getLd())); setValue(R.id.editoffsetAngle, Double.toString(45)); } /** * Prepare the channel spinner */ private void prepareChannelSpinner() { final Spinner channelSpinner = (Spinner) findViewById(R.id.spinnerChannel); final Map<String, OutputChannel> outputChannels = DataManager.getInstance().getOutputChannels(); final List<String> titles = new ArrayList<String>(); for (final Entry<String, OutputChannel> entry : outputChannels.entrySet()) { final IndicatorDefault id = IndicatorDefaults.defaults.get(entry.getKey()); if (id == null) { DebugLogManager.INSTANCE.log("No default indicator for " + entry.getKey(), Log.WARN); } else { final String[] indicatorDetails = new String[2]; indicatorDetails[0] = id.getChannel(); indicatorDetails[1] = id.getTitle(); channels.put(id.getChannel(), indicatorDetails); titles.add(id.getTitle()); } } Collections.sort(titles); final ArrayAdapter<String> channelArrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, titles); // Specify the layout to use when the list of choices appears channelArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); channelSpinner.setAdapter(channelArrayAdapter); final String indicatorChannel = indicator.getChannel(); int channelPosition = channelArrayAdapter.getPosition(IndicatorDefaults.defaults.get(indicatorChannel).getTitle()); if (channelPosition == -1) { channelPosition = 0; } channelSpinner.setSelection(channelPosition); channelSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { boolean ignoreEvent = true; @Override public void onItemSelected(final AdapterView<?> arg0, final View arg1, final int arg2, final long arg3) { // First onItemSelected event of the spinner come from populating it, ignore it! if (ignoreEvent) { ignoreEvent = false; } else { final String name = findNameForTitle(channelSpinner.getSelectedItem().toString()); final IndicatorDefault id = IndicatorDefaults.defaults.get(name); populateFields(id); } } @Override public void onNothingSelected(final AdapterView<?> arg0) { } }); } private String findNameForTitle(final String indicatorTitle) { for (final String[] value : channels.values()) { if (value[1].equals(indicatorTitle)) { return value[0]; } } return ""; } /** * Prepare the orientation spinner */ private void prepareOrientationSpinner() { final Spinner orientationSpinner = (Spinner) findViewById(R.id.indicatorOrientation); // Create an ArrayAdapter using the string array and a default spinner layout final ArrayAdapter<CharSequence> orientationAdapter = ArrayAdapter.createFromResource(getContext(), R.array.indicatororientation, android.R.layout.simple_spinner_item); // Specify the layout to use when the list of choices appears orientationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Apply the adapter to the spinner orientationSpinner.setAdapter(orientationAdapter); // Find the indicator to select final Orientation orientation = indicator.getOrientation(); int selection = 0; if (orientation == Orientation.VERTICAL) { selection = orientationAdapter.getPosition(getContext().getString(R.string.vertical)); } orientationSpinner.setSelection(selection); } /** * Prepare the indicator type spinner */ private void prepareTypeSpinner() { final Spinner typeSpinner = (Spinner) findViewById(R.id.indicatorType); // Create an ArrayAdapter using the string array and a default spinner layout final ArrayAdapter<CharSequence> typeAdapter = ArrayAdapter.createFromResource(getContext(), R.array.indicatortypes, android.R.layout.simple_spinner_item); // Specify the layout to use when the list of choices appears typeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Apply the adapter to the spinner typeSpinner.setAdapter(typeAdapter); // Find the indicator to select final DisplayType indicatorType = indicator.getDisplayType(); int selection = 0; if (indicatorType == DisplayType.NUMERIC) { selection = typeAdapter.getPosition(getContext().getString(R.string.numeric_indicator)); } else if (indicatorType == DisplayType.BAR) { selection = typeAdapter.getPosition(getContext().getString(R.string.bargraph)); } else if (indicatorType == DisplayType.HISTOGRAM) { selection = typeAdapter.getPosition(getContext().getString(R.string.histogram)); } // Select current indicator type typeSpinner.setSelection(selection); typeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(final AdapterView<?> parentView, final View selectedItemView, final int position, final long id) { adjustFieldsForIndicatorType(); } @Override public void onNothingSelected(final AdapterView<?> parentView) { } }); } /** * Depending on the indicator type, decide if specific fields should be displayed or not */ private void adjustFieldsForIndicatorType() { final LinearLayout orientationRow = (LinearLayout) findViewById(R.id.indicatorOrientationRow); final Spinner typeSpinner = (Spinner) findViewById(R.id.indicatorType); final String selectedType = typeSpinner.getSelectedItem().toString(); // Display orientation spinner for bar graph if (selectedType.equals(getContext().getString(R.string.bargraph))) { orientationRow.setVisibility(View.VISIBLE); } else { orientationRow.setVisibility(View.GONE); } } /** * Helper function to set the value of a view based on an ID * * @param id ID of the view * @param value Value to set it to */ private void setValue(final int id, final String value) { final View v = findViewById(id); if (v instanceof TextView) { ((TextView) v).setText(value); } } /** * Save gauge details */ public void saveDetails() { final Spinner gaugeType = (Spinner) findViewById(R.id.indicatorType); final Spinner orientationSpinner = (Spinner) findViewById(R.id.indicatorOrientation); final Spinner channelSpinner = (Spinner) findViewById(R.id.spinnerChannel); final String selectedIndicatorType = gaugeType.getSelectedItem().toString(); Orientation orientation = Orientation.VERTICAL; if (orientationSpinner.getSelectedItem().toString().toLowerCase().equals("horizontal")) { orientation = Orientation.HORIZONTAL; } DisplayType displayType = DisplayType.GAUGE; if (selectedIndicatorType.equals(getContext().getString(R.string.numeric_indicator))) { displayType = DisplayType.NUMERIC; } else if (selectedIndicatorType.equals(getContext().getString(R.string.bargraph))) { displayType = DisplayType.BAR; } else if (selectedIndicatorType.equals(getContext().getString(R.string.histogram))) { displayType = DisplayType.HISTOGRAM; } indicator.setDisplayType(displayType); indicator.setOrientation(orientation); indicator.setChannel(findChannelForTitle(channelSpinner.getSelectedItem().toString())); indicator.setTitle(getValue(R.id.editTitle)); indicator.setUnits(getValue(R.id.editUnits)); indicator.setMax(getValueD(R.id.editHi)); indicator.setMin(getValueD(R.id.editLo)); indicator.setHiD(getValueD(R.id.editHiD)); indicator.setHiW(getValueD(R.id.editHiW)); indicator.setLowD(getValueD(R.id.editLoD)); indicator.setLowW(getValueD(R.id.editLoW)); indicator.setVd(getValueI(R.id.editVD)); indicator.setLd(getValueI(R.id.editLD)); indicator.setOffsetAngle(getValueD(R.id.editoffsetAngle)); mDialogResult.finish(indicator, false); dismiss(); } /** * Ask to remove the indicator from the current dashboard */ public void removeIndicator() { mDialogResult.finish(indicator, true); dismiss(); } /** * * @param value * @return */ private String findChannelForTitle(final String indicatorTitle) { for (final Map.Entry<String, String[]> entry : channels.entrySet()) { final String key = entry.getKey(); final String[] value = entry.getValue(); if (value[1].equals(indicatorTitle)) { return key; } } return ""; } /** * Reset indicators details to the firmware default */ public void resetDetails() { final IndicatorDefault id = IndicatorDefaults.defaults.get(indicator.getChannel()); indicator.copyFrom(id); dismiss(); } /** * Get the value of a specific view as an integer * * @param id The ID of the view to get the value * @return Integer of the value */ private int getValueI(final int id) { int val = 0; final View v = findViewById(id); if (v instanceof TextView) { final String txt = ((TextView) v).getText().toString(); val = Integer.parseInt(txt); } return val; } /** * Get the value of a specific view as an double * * @param id The ID of the view to get the value * @return Double of the value */ private double getValueD(final int id) { double val = 0; final View v = findViewById(id); if (v instanceof TextView) { final String txt = ((TextView) v).getText().toString(); val = Double.parseDouble(txt); } return val; } /** * Get the value of a specific view as a string * * @param id The ID of the view to get the value * @return Double of the value */ private String getValue(final int id) { String val = ""; final View v = findViewById(id); if (v instanceof TextView) { final String txt = ((TextView) v).getText().toString(); val = txt; } return val; } /** * Triggered when the bottom buttons of the dialog are clicked * * @param v */ @Override public void onClick(final View v) { final int which = v.getId(); if (which == R.id.editOK) { saveDetails(); } else if (which == R.id.editReset) { resetDetails(); } else if (which == R.id.editRemove) { removeIndicator(); } } /** * Used by the parent to set a new OnEditIndicatorResult to the dialog * * @param dialogResult */ public void setDialogResult(final OnEditIndicatorResult dialogResult) { mDialogResult = dialogResult; } /** * Interface used to send the data back to the dialog's parent */ public interface OnEditIndicatorResult { void finish(Indicator Indicator, boolean toRemove); } }