/**
* Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
* This file is part of CSipSimple.
*
* CSipSimple is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* If you own a pjsip commercial license you can also redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as an android library.
*
* CSipSimple is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CSipSimple. If not, see <http://www.gnu.org/licenses/>.
*/
package com.csipsimple.widgets;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.ToneGenerator;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import com.csipsimple.R;
import com.csipsimple.utils.Log;
import com.csipsimple.utils.Theme;
import java.util.HashMap;
import java.util.Map;
public class Dialpad extends FrameLayout implements OnClickListener {
private OnDialKeyListener onDialKeyListener;
// Here we need a map to quickly find if the clicked button id is in the map keys
@SuppressLint("UseSparseArrays")
private static final Map<Integer, int[]> DIGITS_BTNS = new HashMap<Integer, int[]>();
static {
DIGITS_BTNS.put(R.id.button0, new int[] {ToneGenerator.TONE_DTMF_0, KeyEvent.KEYCODE_0});
DIGITS_BTNS.put(R.id.button1, new int[] {ToneGenerator.TONE_DTMF_1, KeyEvent.KEYCODE_1});
DIGITS_BTNS.put(R.id.button2, new int[] {ToneGenerator.TONE_DTMF_2, KeyEvent.KEYCODE_2});
DIGITS_BTNS.put(R.id.button3, new int[] {ToneGenerator.TONE_DTMF_3, KeyEvent.KEYCODE_3});
DIGITS_BTNS.put(R.id.button4, new int[] {ToneGenerator.TONE_DTMF_4, KeyEvent.KEYCODE_4});
DIGITS_BTNS.put(R.id.button5, new int[] {ToneGenerator.TONE_DTMF_5, KeyEvent.KEYCODE_5});
DIGITS_BTNS.put(R.id.button6, new int[] {ToneGenerator.TONE_DTMF_6, KeyEvent.KEYCODE_6});
DIGITS_BTNS.put(R.id.button7, new int[] {ToneGenerator.TONE_DTMF_7, KeyEvent.KEYCODE_7});
DIGITS_BTNS.put(R.id.button8, new int[] {ToneGenerator.TONE_DTMF_8, KeyEvent.KEYCODE_8});
DIGITS_BTNS.put(R.id.button9, new int[] {ToneGenerator.TONE_DTMF_9, KeyEvent.KEYCODE_9});
DIGITS_BTNS.put(R.id.buttonpound, new int[] {ToneGenerator.TONE_DTMF_P, KeyEvent.KEYCODE_POUND});
DIGITS_BTNS.put(R.id.buttonstar, new int[] {ToneGenerator.TONE_DTMF_S, KeyEvent.KEYCODE_STAR});
};
private static final SparseArray<String> DIGITS_NAMES = new SparseArray<String>();
private static final String THIS_FILE = null;
static {
DIGITS_NAMES.put(R.id.button0, "0");
DIGITS_NAMES.put(R.id.button1, "1");
DIGITS_NAMES.put(R.id.button2, "2");
DIGITS_NAMES.put(R.id.button3, "3");
DIGITS_NAMES.put(R.id.button4, "4");
DIGITS_NAMES.put(R.id.button5, "5");
DIGITS_NAMES.put(R.id.button6, "6");
DIGITS_NAMES.put(R.id.button7, "7");
DIGITS_NAMES.put(R.id.button8, "8");
DIGITS_NAMES.put(R.id.button9, "9");
DIGITS_NAMES.put(R.id.buttonpound, "pound");
DIGITS_NAMES.put(R.id.buttonstar, "star");
};
/**
* Interface definition for a callback to be invoked when a tab is triggered
* by moving it beyond a target zone.
*/
public interface OnDialKeyListener {
/**
* Called when the user make an action
*
* @param keyCode keyCode pressed
* @param dialTone corresponding dialtone
*/
void onTrigger(int keyCode, int dialTone);
}
public Dialpad(Context context) {
super(context);
initLayout(context);
}
public Dialpad(Context context, AttributeSet attrs) {
super(context, attrs);
initLayout(context);
}
private void initLayout(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.dialpad, this, true);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
for(int buttonId : DIGITS_BTNS.keySet()) {
ImageButton button = (ImageButton) findViewById(buttonId);
if(button != null) {
button.setOnClickListener(this);
}
}
}
/**
* Registers a callback to be invoked when the user triggers an event.
*
* @param listener
* the OnTriggerListener to attach to this view
*/
public void setOnDialKeyListener(OnDialKeyListener listener) {
onDialKeyListener = listener;
}
private void dispatchDialKeyEvent(int buttonId) {
if (onDialKeyListener != null && DIGITS_BTNS.containsKey(buttonId)) {
int[] datas = DIGITS_BTNS.get(buttonId);
onDialKeyListener.onTrigger(datas[1], datas[0]);
}
}
@Override
public void onClick(View v) {
dispatchDialKeyEvent(v.getId());
}
/*
boolean mForceWidth = false;
public void setForceWidth(boolean forceWidth) {
mForceWidth = forceWidth;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(mForceWidth) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), getMeasuredHeight());
}
};
*/
public void applyTheme(Theme t) {
Log.d(THIS_FILE, "Theming in progress");
for(int buttonId : DIGITS_BTNS.keySet()) {
ImageButton b = (ImageButton) findViewById(buttonId);
// We need to use state list as reused
t.applyBackgroundStateListDrawable(b, "btn_dial");
// Src of button
Drawable src = t.getDrawableResource("dial_num_"+DIGITS_NAMES.get(buttonId));
if(src != null) {
b.setImageDrawable(src);
}
// Padding of button
t.applyLayoutMargin(b, "dialpad_btn_margin");
}
}
}