/*
* Copyright (C) 2011 The original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.zapta.apps.maniana.settings;
import static com.zapta.apps.maniana.util.Assertions.checkNotNull;
import java.util.ArrayList;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
import com.mobeta.android.dslv.DragSortListView.DropListener;
import com.zapta.apps.maniana.R;
import com.zapta.apps.maniana.model.ItemColor;
import com.zapta.apps.maniana.util.BitmapUtil;
import com.zapta.apps.maniana.util.DisplayUtil;
/**
* Dialog for selecting and ordering the tasks colors. Used by ItemColorsPreference.
*
* @author Tal Dayan
*/
public class ItemColorsPreferenceDialog {
/** Represents a single item in the task colors list. */
private static class ListItem {
private final ItemColor itemColor;
private boolean isEnabled;
private ListItem(ItemColor itemColor, boolean isEnabled) {
this.itemColor = itemColor;
this.isEnabled = isEnabled;
}
}
public static interface ItemColorsChangeListener {
void onTasksColorsSetChange(List<ItemColor> enabledItemColors);
}
/** Adapter for the tasks color lists. Contains the underlying list data. */
private static class ColorAdapter extends BaseAdapter implements DropListener {
private final Context mContext;
final float mDensity;
private final ArrayList<ListItem> listItems = new ArrayList<ListItem>();
/**
* EnabledItemColors is assumed to contains no duplicates. May be empty. Order represents
* colors order.
*/
public ColorAdapter(Context context, List<ItemColor> enabledItemColors) {
super();
this.mContext = context;
this.mDensity = DisplayUtil.getDensity(context);
boolean itemsAdded[] = new boolean[ItemColor.values().length];
// Add the enabled ones. Avoid duplicates.
for (ItemColor itemColor : enabledItemColors) {
// NOTE: we assume no duplicates
itemsAdded[itemColor.ordinal()] = true;
listItems.add(new ListItem(itemColor, true));
}
// Add the rest as disabled.
for (ItemColor itemColor : ItemColor.values()) {
if (!itemsAdded[itemColor.ordinal()]) {
listItems.add(new ListItem(itemColor, false));
}
}
}
@Override
public int getCount() {
return listItems.size();
}
@Override
public Object getItem(int position) {
return listItems.get(position);
}
@Override
public long getItemId(int position) {
// We use the position as ID
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
// If not recycling an existing item view, create a new one.
if (view == null) {
final LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_colors_item_layout, parent, false);
}
final ListItem listItem = listItems.get(position);
// Set color
final ImageView imageView = (ImageView) view.findViewById(R.id.item_colors_item_image);
imageView.setImageBitmap(BitmapUtil.getPreferenceColorPreviewBitmap(0xff888888,
listItem.isEnabled, mDensity));
imageView.setImageBitmap(BitmapUtil.getPreferenceColorPreviewBitmap(
listItem.itemColor.getColor(0xff666666), listItem.isEnabled, mDensity));
// Set text
final TextView textView = (TextView) view.findViewById(R.id.item_colors_item_text);
textView.setText(mContext.getString(listItem.itemColor.nameResourceId));
// Set checkbox
final CheckBox checkboxView = (CheckBox) view
.findViewById(R.id.item_colors_item_checkbox);
// Disable the old listener so we don't callback the handle when setting a reused view.
checkboxView.setOnCheckedChangeListener(null);
checkboxView.setChecked(listItem.isEnabled);
checkboxView.setClickable(false);
final LinearLayout clickArea = (LinearLayout) view
.findViewById(R.id.item_colors_item_clickable_area);
clickArea.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleColorClick(checkboxView, position);
}
});
return view;
}
private void handleColorClick(CheckBox checkboxView, int position) {
final ListItem listItem = listItems.get(position);
final boolean newState = !checkboxView.isChecked();
checkboxView.setChecked(newState);
listItem.isEnabled = newState;
// Refresh the display to propagate color change due to check change.
notifyDataSetChanged();
}
/** From DragListener interface. Called when the user completes a drag */
@Override
public void drop(int from, int to) {
// NOTE: we don't filter out the special case of from == to, since it
// is handled gracefully.
final ListItem listItem = listItems.remove(from);
listItems.add(to, listItem);
notifyDataSetChanged();
}
}
private static class MyDSController extends DragSortController {
DragSortListView mDslv;
ColorAdapter adapter;
public MyDSController(DragSortListView dslv, ColorAdapter adapter) {
super(dslv);
this.mDslv = dslv;
this.adapter = adapter;
// View id in the item layout that is used as a drag handle.
setDragHandleId(R.id.item_colors_item_drag_handle);
}
@Override
public View onCreateFloatView(int position) {
checkNotNull(adapter);
View v = adapter.getView(position, null, mDslv);
checkNotNull(v);
checkNotNull(v.getBackground());
v.getBackground().setLevel(10000);
return v;
}
@Override
public void onDestroyFloatView(View floatView) {
// do nothing; blocks super from crashing
}
}
public static AlertDialog CreateDialog(Context context, List<ItemColor> enabledColors,
final ItemColorsChangeListener listener) {
checkNotNull(listener);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View layout = inflater.inflate(R.layout.item_colors_layout, null);
final DragSortListView dslv = (DragSortListView) layout
.findViewById(R.id.item_colors_list_view);
final ColorAdapter adapter = new ColorAdapter(context, enabledColors);
dslv.setAdapter(adapter);
final MyDSController dslvController = new MyDSController(dslv, adapter);
dslv.setFloatViewManager(dslvController);
dslv.setOnTouchListener(dslvController);
dslv.setDragEnabled(true);
dslv.setDropListener(adapter);
builder.setView(layout);
builder.setTitle(R.string.settings_select_task_colors_dialog_title);
builder.setNegativeButton("Cancel", null);
builder.setPositiveButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
List<ItemColor> enabledItemColors = new ArrayList<ItemColor>();
for (ListItem item : adapter.listItems) {
if (item.isEnabled) {
enabledItemColors.add(item.itemColor);
}
}
listener.onTasksColorsSetChange(enabledItemColors);
}
});
return builder.create();
}
}