aboutsummaryrefslogtreecommitdiffstats
path: root/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconPopupDelegate.java
blob: 48952cdb33b2307076fb406941db5ef3e0ef8650 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package github.ankushsachdeva.emojicon;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.PopupWindow;

/**
 * Created by aleksandr.naumov on 15.05.2015.
 */
public class EmojiconPopupDelegate {
    public static final String KEY_EMOJI_POPUP_SHOWN = "key_emoji_popup_shown";
    private Context mContext;
    private EmojiconsPopup mPopup;
    private EditText mPrefferredEditText;
    private boolean mPendingShow;
    private View mRootView;

    @Nullable
    private PopupShownListener mListener;

    public void setShowHideListener(PopupShownListener listener) {
        this.mListener = listener;
    }

    public void setInputEditText(EditText editText) {
        mPrefferredEditText = editText;
    }

    public void attach(View rootView) {
        mContext = createThemedContext(rootView.getContext());
        mRootView = rootView;
        mPopup = new EmojiconsPopup(rootView, mContext);
        mPopup.setOnDismissListener(new DismissListener());
        mPopup.setOnSoftKeyboardOpenCloseListener(new KeyboardOpenCloseListener());
        mPopup.setOnEmojiconClickedListener(new EmojiconClickedListener());
        mPopup.setOnEmojiconBackspaceClickedListener(new BackspaceClickedListener());
        mPopup.attachGlobalLayoutListener();
        if (mPendingShow) {
            show();
        }
    }

    private Context createThemedContext(Context context) {
        TypedArray typedArray = context.obtainStyledAttributes(null, new int[]{R.attr.emojicon_theme});
        int themeId = typedArray.getResourceId(0, R.style.Emojicon);
        typedArray.recycle();
        return new ContextThemeWrapper(context, themeId);
    }

    public void detach() {
        hide();
        if (mPopup != null) {
            mPopup.detachGlobalLayoutListener();
            mPopup = null;
        }
        mContext = null;
        mPrefferredEditText = null;
        mRootView = null;
    }

    public void saveState(Bundle bundle) {
        bundle.putBoolean(KEY_EMOJI_POPUP_SHOWN, isShown());
    }

    public void restoreState(Bundle bundle) {
        if (bundle.containsKey(KEY_EMOJI_POPUP_SHOWN)) {
            if (bundle.getBoolean(KEY_EMOJI_POPUP_SHOWN)) {
                show();
            } else {
                hide();
            }
        }
    }

    public void show() {
        if (mPopup != null && !mPopup.isShowing()) {
            if (mPopup.isKeyBoardOpen()) {
                //If keyboard is visible, simply show the emoji popup
                mPopup.showAtBottom();
            } else {
                //else, open the text keyboard first and immediately after that show the emoji popup
                mPrefferredEditText.setFocusableInTouchMode(true);
                mPrefferredEditText.requestFocus();
                mPopup.showAtBottomPending();
                final InputMethodManager inputMethodManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
                inputMethodManager.showSoftInput(mPrefferredEditText, InputMethodManager.SHOW_IMPLICIT);
            }
            mPendingShow = false;
            notifyShown();
        } else if (!mPendingShow) {
            mPendingShow = true;
            notifyShown();
        }
    }

    public void hide() {
        if (mPopup != null && mPopup.isShowing()) {
            mPopup.dismiss();
            notifyHidden();
        } else if (mPendingShow) {
            mPendingShow = false;
            notifyHidden();
        }
    }

    private void notifyShown() {
        if (mListener != null) {
            mListener.onPopupShown();
        }
    }

    private void notifyHidden() {
        if (mListener != null) {
            mListener.onPopupHidden();
        }
    }

    public boolean isShown() {
        return mPopup != null ? mPopup.isShowing() : mPendingShow;
    }

    public void toggle() {
        if (isShown()) {
            hide();
        } else {
            show();
        }
    }

    @Nullable
    public EditText findFocusedEditText() {
        View view = mRootView != null ? mRootView.findFocus() : null;
        if (view instanceof EditText) {
            return (EditText) view;
        } else {
            return null;
        }
    }

    public interface PopupShownListener {
        void onPopupShown();

        void onPopupHidden();
    }

    private class BackspaceClickedListener implements EmojiconsPopup.OnEmojiconBackspaceClickedListener {
        @Override
        public void onEmojiconBackspaceClicked(View v) {
            EditText currentFocus = findFocusedEditText();
            if (currentFocus != null) {
                KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
                currentFocus.dispatchKeyEvent(event);
            }
        }
    }

    private class EmojiconClickedListener implements EmojiconsPopup.OnEmojiconClickedListener {

        @Override
        public void onEmojiconClicked(Emojicon emojicon) {
            EditText currentFocus = findFocusedEditText();
            if (currentFocus != null) {
                String textToInsert = emojicon.toString();
                int start = Math.max(currentFocus.getSelectionStart(), 0);
                int end = Math.max(currentFocus.getSelectionEnd(), 0);
                currentFocus.getText().replace(Math.min(start, end), Math.max(start, end), textToInsert, 0, textToInsert.length());
            }
        }
    }

    private class KeyboardOpenCloseListener implements EmojiconsPopup.OnSoftKeyboardOpenCloseListener {
        @Override
        public void onKeyboardOpen(int keyBoardHeight) {

        }

        @Override
        public void onKeyboardClose() {
            hide();
        }
    }

    private class DismissListener implements PopupWindow.OnDismissListener {
        @Override
        public void onDismiss() {
            notifyHidden();
        }
    }
}