package org.ohmage.controls;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.ohmage.R;
import org.ohmage.UIUtils;
import org.ohmage.activity.DashboardActivity;
import org.ohmage.logprobe.Analytics;
import java.util.ArrayList;
import java.util.List;
public class ActionBarControl extends LinearLayout {
private final Activity mActivity;
// view references
private final TextView mTitleText;
private final ImageButton mHomeButton;
private final ProgressBar mProgressSpinner;
private ImageView mHomeSeparator;
// functionality
private final List<ImageButton> mActionButtons;
private final List<View> mSeparators;
private ActionListener mActionBarClickedListener;
private final OnClickListener mActionButtonClickListener;
// style flags
private boolean mShowLogo;
private boolean mShowHome;
public ActionBarControl(Context context, AttributeSet attrs) {
super(context, attrs);
mActivity = (Activity)context;
// load up the elements of the actionbar from controls_actionbar.xml
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.controls_actionbar, this, true);
// set up some basic layout parameters, like width x height and background
this.setBackgroundResource(R.drawable.title_bkgnd);
// gather member references
mTitleText = (TextView) findViewById(R.id.controls_actionbar_title);
mHomeButton = (ImageButton) findViewById(R.id.controls_actionbar_home);
mProgressSpinner = (ProgressBar) findViewById(R.id.controls_actionbar_progress);
// hook up buttons
mHomeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Analytics.widget(v);
mActivity.startActivity(new Intent(mActivity, DashboardActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (!UIUtils.isHoneycomb()) {
mActivity.overridePendingTransition(R.anim.home_enter, R.anim.home_exit);
}
mActivity.finish();
}
});
// serves as a single handler for routing all action button presses to a user-supplied callback
mActionButtonClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
Analytics.widget(v);
// route clicks on the action bar to the user-supplied action handler, if present
if (mActionBarClickedListener != null)
mActionBarClickedListener.onActionClicked(v.getId());
}
};
// holds a list of buttons that we manage
mActionButtons = new ArrayList<ImageButton>();
mSeparators = new ArrayList<View>();
// apply the xml-specified attributes, too
initStyles(attrs);
}
public ActionBarControl(Context context) {
this(context, null);
}
/**
* Initializes the appearance of the control based on the attributes passed from the xml.
* @param attrs the collection of attributes, usually provided in the control's constructor
*/
protected void initStyles(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ActivityBarControl);
mShowLogo = a.getBoolean(R.styleable.ActivityBarControl_showlogo, false);
String titleText = a.getString(R.styleable.ActivityBarControl_title);
mHomeSeparator = (ImageView) findViewById(R.id.controls_actionbar_homebutton_separator);
mTitleText.setText(titleText);
setShowLogo(mShowLogo);
// and set whether or not the home button appears
setHomeVisibility(a.getBoolean(R.styleable.ActivityBarControl_showhome, true));
}
public void setShowLogo(boolean showLogo) {
ImageView logo = (ImageView) findViewById(R.id.controls_actionbar_logo);
if (showLogo) {
logo.setVisibility(VISIBLE);
mHomeSeparator.setVisibility(GONE);
mHomeButton.setVisibility(GONE);
mTitleText.setVisibility(INVISIBLE);
} else {
logo.setVisibility(GONE);
mHomeSeparator.setVisibility(VISIBLE);
mHomeButton.setVisibility(VISIBLE);
mTitleText.setVisibility(VISIBLE);
}
}
/**
* Set the visibility of the home button. Note that this is overridden by "showlogo";
* if the logo is visible, the home button will never appear.
*
* @param isVisible if true, home button is shown; if false, home button is hidden
*/
public void setHomeVisibility(boolean isVisible) {
if (!isVisible || mShowLogo) {
mHomeSeparator.setVisibility(GONE);
mHomeButton.setVisibility(GONE);
mShowHome = false;
}
else {
mHomeSeparator.setVisibility(VISIBLE);
mHomeButton.setVisibility(VISIBLE);
mShowHome = true;
}
}
/**
* Sets the title for the action bar, which is displayed when showlogo is false.
*
* @param text the text to display in the action bar
*/
public void setTitle(CharSequence text) {
mTitleText.setText(text);
}
/**
* Shows or hides a progress bar "spinner" depending on the value of isVisible. Generally shown
* to indicate that a lengthy background operation is in progress and hidden once it's done.
*
* @param isVisible shows spinner if true, hides it if false
*/
public void setProgressVisible(boolean isVisible) {
mProgressSpinner.setVisibility(isVisible?VISIBLE:GONE);
}
/**
* Adds a command to the action bar, identified in callbacks by buttonID. Note that buttonID will be used
* as the ID of the ImageButton that this method creates.
*
* @param buttonID an id which should uniquely identify this command, up to the caller to create
* @param description a string which defines this command, used for accessibility
* @param resid a drawable to render as the icon. should be the same size as the action bar (i.e. 40x40px hdpi)
*/
public void addActionBarCommand(int buttonID, String description, int resID) {
// inflate a new separator and button from the dashboard templates
// we're doing this mostly to add a predefined style to the view/button, which is currently impossible without xml
View newSeparator = mActivity.getLayoutInflater().inflate(R.layout.controls_actionbar_separator, this);
ImageButton newButton = (ImageButton) mActivity.getLayoutInflater().inflate(R.layout.controls_actionbar_button, null);
newButton.setId(buttonID);
newButton.setContentDescription(description);
newButton.setImageResource(resID);
// attach to our existing listener for routing clicks through the callback
newButton.setOnClickListener(mActionButtonClickListener);
mSeparators.add(newSeparator);
mActionButtons.add(newButton);
// add to the parent layout now
this.addView(newButton, new LayoutParams(dpToPixels(45), LayoutParams.FILL_PARENT));
}
/**
* Removes all the action bar commands. This is somewhat useful if you want to recompose the action bar from scratch.
*/
public void clearActionBarCommands() {
for (ImageButton button : mActionButtons)
removeView(button);
for (View sep : mSeparators)
removeView(sep);
}
/**
* Set a callback to be invoked when the user presses any button in the action bar.
*
* @param listener a listener whose {@link ActionListener#onActionClicked(int)} method will be called when a click occurs.
*/
public void setOnActionListener(ActionListener listener) {
mActionBarClickedListener = listener;
}
/**
* Callback that receives action bar button presses when registered with {@link ActionBarControl#setOnActionListener(ActionListener)}
* @author faisal
*
*/
public interface ActionListener {
void onActionClicked(int commandID);
}
// utility method for converting dp to pixels, since the setters only take pixel values :\
private int dpToPixels(int dp) {
final float scale = getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
}