package org.ebookdroid.common.keysbinding;
import org.sufficientlysecure.viewer.R;
import org.ebookdroid.ui.viewer.IActivityController;
import android.app.Dialog;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.emdev.common.android.AndroidVersion;
import org.emdev.ui.actions.ActionEx;
import org.emdev.ui.adapters.ActionsAdapter;
import org.emdev.utils.LayoutUtils;
import org.emdev.utils.LengthUtils;
public class KeyBindingsDialog extends Dialog {
private final ActionsAdapter actionsAdapter;
private final KeyGroups groups = new KeyGroups();
public KeyBindingsDialog(final IActivityController base) {
super(base.getContext());
setTitle("Keys binding");
actionsAdapter = new ActionsAdapter(getContext());
final ExpandableListView list = new ExpandableListView(getContext());
final KeyGroups groups = initKeyActions();
list.setAdapter(groups);
LayoutUtils.fillInParent(null, list);
setContentView(list);
}
private KeyGroups initKeyActions() {
final KeyGroup management = groups.add("Management keys");
management.addInterval(KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_VOLUME_DOWN);
management.addInterval(96 /* KeyEvent.KEYCODE_BUTTON_A */, 110/* KeyEvent.KEYCODE_BUTTON_MODE */);
final KeyGroup phone = groups.add("Phone keys");
phone.add(KeyEvent.KEYCODE_SOFT_LEFT, KeyEvent.KEYCODE_SOFT_RIGHT);
phone.add(KeyEvent.KEYCODE_CALL, KeyEvent.KEYCODE_ENDCALL);
phone.addInterval(KeyEvent.KEYCODE_0, KeyEvent.KEYCODE_POUND);
final KeyGroup keyboard = groups.add("Keyboard keys");
keyboard.addInterval(KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_Z);
keyboard.add(KeyEvent.KEYCODE_COMMA, KeyEvent.KEYCODE_PERIOD);
keyboard.add(KeyEvent.KEYCODE_TAB, KeyEvent.KEYCODE_SPACE);
keyboard.add(KeyEvent.KEYCODE_TAB, KeyEvent.KEYCODE_SPACE);
keyboard.addInterval(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_AT);
keyboard.add(KeyEvent.KEYCODE_TAB, KeyEvent.KEYCODE_SPACE);
if (!AndroidVersion.lessThan3x) {
keyboard.addInterval(/* KeyEvent.KEYCODE_PAGE_UP */92, /* (KeyEvent.KEYCODE_PAGE_DOWN */93);
keyboard.addInterval(/* KeyEvent.KEYCODE_MOVE_HOME */122, /* KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN */163);
}
final KeyGroup service = groups.add("Service keys");
service.add(KeyEvent.KEYCODE_CAMERA, KeyEvent.KEYCODE_CLEAR);
service.addInterval(KeyEvent.KEYCODE_NOTIFICATION, KeyEvent.KEYCODE_MUTE);
return groups;
}
@Override
protected void onStart() {
LayoutUtils.maximizeWindow(getWindow());
}
@Override
protected void onStop() {
super.onStop();
for (final KeyGroup group : groups.groups) {
for (final KeyAction action : group.actions) {
final Integer actionId = action.action != null ? ActionEx.getActionId(action.action) : null;
if (actionId != null) {
KeyBindingsManager.addAction(actionId, action.code);
} else {
KeyBindingsManager.removeAction(action.code);
}
}
}
KeyBindingsManager.persist();
}
protected void updateAction(final Spinner view) {
final KeyAction action = (KeyAction) view.getTag();
final String name = action.action;
if (LengthUtils.isNotEmpty(name)) {
view.setSelection(actionsAdapter.getPosition(name));
return;
}
view.setSelection(0);
}
public class KeyAction {
final int code;
final String label;
String action;
public KeyAction(final int code) {
this.code = code;
String label = KeyBindingsManager.keyCodeToString(code);
this.label = label + " [" + code + "]";
final Integer actionId = KeyBindingsManager.getAction(code);
this.action = actionId != null ? ActionEx.getActionName(actionId) : null;
}
}
public class KeyGroup {
final String label;
final Map<Integer, KeyAction> keys = new LinkedHashMap<Integer, KeyAction>();
final List<KeyAction> actions = new ArrayList<KeyAction>();
public KeyGroup(final String label) {
this.label = label;
}
public void add(final int... codes) {
for (final int code : codes) {
final KeyAction value = new KeyAction(code);
keys.put(code, value);
actions.add(value);
}
}
public void addInterval(final int first, final int last) {
for (int code = first; code <= last; code++) {
final KeyAction value = new KeyAction(code);
keys.put(code, value);
actions.add(value);
}
}
}
public class KeyGroups extends BaseExpandableListAdapter implements OnItemSelectedListener {
final List<KeyGroup> groups = new ArrayList<KeyGroup>();
public KeyGroup add(final String label) {
final KeyGroup group = new KeyGroup(label);
groups.add(group);
return group;
}
@Override
public int getGroupCount() {
return groups.size();
}
@Override
public KeyGroup getGroup(final int groupPosition) {
return groups.get(groupPosition);
}
@Override
public long getGroupId(final int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(final int groupPosition, final boolean isExpanded, final View convertView,
final ViewGroup parent) {
View container = null;
TextView view = null;
if (convertView == null) {
container = LayoutInflater.from(getContext()).inflate(R.layout.keybinding_group, parent, false);
} else {
container = convertView;
}
view = (TextView) container.findViewById(R.id.keybinding_groupText);
view.setText(getGroup(groupPosition).label);
return container;
}
@Override
public int getChildrenCount(final int groupPosition) {
return getGroup(groupPosition).actions.size();
}
@Override
public KeyAction getChild(final int groupPosition, final int childPosition) {
return getGroup(groupPosition).actions.get(childPosition);
}
@Override
public View getChildView(final int groupPosition, final int childPosition, final boolean isLastChild,
View convertView, final ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.keybinding_action, parent, false);
}
final KeyAction action = getChild(groupPosition, childPosition);
final TextView keyView = (TextView) convertView.findViewById(R.id.keybinding_key);
keyView.setText(action.label);
final Spinner actionsView = (Spinner) convertView.findViewById(R.id.keybinding_actions);
actionsView.setOnItemSelectedListener(this);
actionsView.setAdapter(actionsAdapter);
actionsView.setTag(action);
updateAction(actionsView);
return convertView;
}
@Override
public long getChildId(final int groupPosition, final int childPosition) {
return childPosition;
}
@Override
public boolean isChildSelectable(final int groupPosition, final int childPosition) {
return true;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public void onItemSelected(final AdapterView<?> parent, final View view, final int position, final long id) {
final String actionId = actionsAdapter.getActionId(position);
final KeyAction action = (KeyAction) parent.getTag();
action.action = LengthUtils.unsafeString(actionId);
}
@Override
public void onNothingSelected(final AdapterView<?> parent) {
final KeyAction action = (KeyAction) parent.getTag();
action.action = null;
}
}
}