session-android/src/org/thoughtcrime/securesms/components/EmojiDrawer.java

256 lines
8.5 KiB
Java
Raw Normal View History

2013-06-28 03:57:27 +00:00
package org.thoughtcrime.securesms.components;
import android.annotation.TargetApi;
2013-06-28 03:57:27 +00:00
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION_CODES;
2013-06-28 03:57:27 +00:00
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
2013-06-28 03:57:27 +00:00
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
2013-06-28 03:57:27 +00:00
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.astuetz.PagerSlidingTabStrip;
2013-06-28 03:57:27 +00:00
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.Emoji;
public class EmojiDrawer extends KeyboardAwareLinearLayout {
2013-06-28 03:57:27 +00:00
private static final int RECENT_TYPE = 0;
private static final int ALL_TYPE = 1;
private FrameLayout[] gridLayouts = new FrameLayout[Emoji.PAGES.length+1];
private EditText composeText;
private Emoji emoji;
private ViewPager pager;
private PagerSlidingTabStrip strip;
2013-06-28 03:57:27 +00:00
@SuppressWarnings("unused")
2013-06-28 03:57:27 +00:00
public EmojiDrawer(Context context) {
super(context);
initialize();
}
@SuppressWarnings("unused")
2013-06-28 03:57:27 +00:00
public EmojiDrawer(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
@SuppressWarnings("unused")
@TargetApi(VERSION_CODES.HONEYCOMB)
2013-06-28 03:57:27 +00:00
public EmojiDrawer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
public void setComposeEditText(EditText composeText) {
this.composeText = composeText;
}
public boolean isOpen() {
return getVisibility() == View.VISIBLE;
}
private void initialize() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
2013-06-28 03:57:27 +00:00
inflater.inflate(R.layout.emoji_drawer, this, true);
initializeResources();
initializeEmojiGrid();
}
private void initializeResources() {
this.pager = (ViewPager ) findViewById(R.id.emoji_pager);
this.strip = (PagerSlidingTabStrip ) findViewById(R.id.tabs);
this.emoji = Emoji.getInstance(getContext());
}
public void hide() {
setVisibility(View.GONE);
}
public void show() {
int keyboardHeight = getKeyboardHeight();
Log.w("EmojiDrawer", "setting emoji drawer to height " + keyboardHeight);
setLayoutParams(new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, keyboardHeight));
requestLayout();
setVisibility(View.VISIBLE);
}
private void initializeEmojiGrid() {
LayoutInflater inflater = LayoutInflater.from(getContext());
for (int i = 0; i < gridLayouts.length; i++) {
gridLayouts[i] = (FrameLayout) inflater.inflate(R.layout.emoji_grid_layout, pager, false);
final GridView gridView = (GridView) gridLayouts[i].findViewById(R.id.emoji);
gridLayouts[i].setTag(gridView);
final int type = (i == 0 ? RECENT_TYPE : ALL_TYPE);
gridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.emoji_drawer_size) + 2*getResources().getDimensionPixelSize(R.dimen.emoji_drawer_item_padding));
gridView.setAdapter(new EmojiGridAdapter(type, i-1));
gridView.setOnItemClickListener(new EmojiClickListener(ALL_TYPE));
}
2013-06-28 03:57:27 +00:00
pager.setAdapter(new EmojiPagerAdapter());
if (emoji.getRecentlyUsedAssetCount() <= 0) {
pager.setCurrentItem(1);
}
strip.setTabPaddingLeftRight(getResources().getDimensionPixelSize(R.dimen.emoji_drawer_left_right_padding));
strip.setAllCaps(false);
strip.setShouldExpand(true);
strip.setUnderlineColorResource(R.color.emoji_tab_underline);
strip.setIndicatorColorResource(R.color.emoji_tab_indicator);
strip.setIndicatorHeight(getResources().getDimensionPixelSize(R.dimen.emoji_drawer_indicator_height));
strip.setViewPager(pager);
2013-06-28 03:57:27 +00:00
}
private class EmojiClickListener implements AdapterView.OnItemClickListener {
private final int type;
public EmojiClickListener(int type) {
this.type = type;
}
2013-06-28 03:57:27 +00:00
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Integer unicodePoint = (Integer) view.getTag();
insertEmoji(composeText, unicodePoint);
if (type != RECENT_TYPE) {
emoji.setRecentlyUsed(Integer.toHexString(unicodePoint));
((BaseAdapter)((GridView)gridLayouts[0].getTag()).getAdapter()).notifyDataSetChanged();
}
}
2013-06-28 03:57:27 +00:00
private void insertEmoji(EditText editText, Integer unicodePoint) {
final char[] chars = Character.toChars(unicodePoint);
String characters = new String(chars);
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
2013-06-28 03:57:27 +00:00
CharSequence text = emoji.emojify(characters, new Emoji.InvalidatingPageLoadedListener(composeText));
editText.getText().replace(Math.min(start, end), Math.max(start, end), text, 0, text.length());
editText.setSelection(end+chars.length);
2013-06-28 03:57:27 +00:00
}
}
private class EmojiGridAdapter extends BaseAdapter {
private final int type;
private final int page;
private final int emojiSize;
public EmojiGridAdapter(int type, int page) {
this.type = type;
this.page = page;
emojiSize = (int) getResources().getDimension(R.dimen.emoji_drawer_size);
}
2013-06-28 03:57:27 +00:00
@Override
public int getCount() {
if (type == RECENT_TYPE) return emoji.getRecentlyUsedAssetCount();
else return Emoji.PAGES[page].length;
2013-06-28 03:57:27 +00:00
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
2013-06-28 03:57:27 +00:00
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final ImageView view;
final int pad = getResources().getDimensionPixelSize(R.dimen.emoji_drawer_item_padding);
if (convertView != null && convertView instanceof ImageView) {
view = (ImageView) convertView;
} else {
ImageView imageView = new ImageView(getContext());
imageView.setPadding(pad, pad, pad, pad);
imageView.setLayoutParams(new AbsListView.LayoutParams(emojiSize + 2*pad, emojiSize + 2*pad));
view = imageView;
2013-06-28 03:57:27 +00:00
}
final Drawable drawable;
final Integer unicodeTag;
if (type == ALL_TYPE) {
unicodeTag = Emoji.PAGES[page][position];
drawable = emoji.getEmojiDrawable(new Emoji.DrawInfo(page, position),
Emoji.EMOJI_HUGE,
new Emoji.InvalidatingPageLoadedListener(view));
} else {
Pair<Integer, Drawable> recentlyUsed = emoji.getRecentlyUsed(position,
Emoji.EMOJI_HUGE,
new Emoji.InvalidatingPageLoadedListener(view));
unicodeTag = recentlyUsed.first;
drawable = recentlyUsed.second;
}
view.setImageDrawable(drawable);
view.setPadding(pad, pad, pad, pad);
view.setTag(unicodeTag);
return view;
2013-06-28 03:57:27 +00:00
}
}
private class EmojiPagerAdapter extends PagerAdapter implements PagerSlidingTabStrip.IconTabProvider {
2013-06-28 03:57:27 +00:00
@Override
public int getCount() {
return gridLayouts.length;
2013-06-28 03:57:27 +00:00
}
@Override
public boolean isViewFromObject(View view, Object o) {
return view == o;
}
public Object instantiateItem(ViewGroup container, int position) {
if (position < 0 || position >= gridLayouts.length)
throw new AssertionError("position out of range!");
2013-06-28 03:57:27 +00:00
container.addView(gridLayouts[position], 0);
2013-06-28 03:57:27 +00:00
return gridLayouts[position];
}
2013-06-28 03:57:27 +00:00
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Log.w("EmojiDrawer", "destroying item at " + position);
container.removeView(gridLayouts[position]);
}
@Override
public int getPageIconResId(int i) {
switch (i) {
case 0: return R.drawable.emoji_category_recent;
case 1: return R.drawable.emoji_category_smile;
case 2: return R.drawable.emoji_category_flower;
case 3: return R.drawable.emoji_category_bell;
case 4: return R.drawable.emoji_category_car;
case 5: return R.drawable.emoji_category_symbol;
default: return 0;
}
2013-06-28 03:57:27 +00:00
}
}
}