blob: 334cdf5dd7a0f7ec455b1fb87c27abd932183a8b [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.example.android.autofillkeyboard;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
/** Controls the visible virtual keyboard view. */
final class Keyboard {
private static final int NUM_STATES = 4;
private static final int STATE_SHIFT = 1;
private static final int STATE_SYMBOL = 2;
private final AutofillImeService mAutofillImeService;
private final int mViewResId;
private final SparseArray<String> mKeyMapping;
private View mKeyboardView;
private int mState;
private Keyboard(AutofillImeService autofillImeService, int viewResId,
SparseArray<String> keyMapping) {
this.mAutofillImeService = autofillImeService;
this.mViewResId = viewResId;
this.mKeyMapping = keyMapping;
this.mState = 0;
}
private static String getLabel(String data) {
if ("SHI".equals(data)) {
return "↑";
} else if ("DEL".equals(data)) {
return "←";
} else if ("SYM".equals(data)) {
return "?123";
} else if ("SPA".equals(data)) {
return "[ ]";
} else if ("ENT".equals(data)) {
return "↩";
} else {
return data;
}
}
static Keyboard qwerty(AutofillImeService autofillImeService) {
SparseArray<String> keyMapping = new SparseArray<>();
keyMapping.put(R.id.key_pos_0_0, "qQ1\u007E");
keyMapping.put(R.id.key_pos_0_1, "wW2\u0060");
keyMapping.put(R.id.key_pos_0_2, "eE3\u007C");
keyMapping.put(R.id.key_pos_0_3, "rR4\u2022");
keyMapping.put(R.id.key_pos_0_4, "tT5\u221A");
keyMapping.put(R.id.key_pos_0_5, "yY6\u03C0");
keyMapping.put(R.id.key_pos_0_6, "uU7\u00F7");
keyMapping.put(R.id.key_pos_0_7, "iI8\u00D7");
keyMapping.put(R.id.key_pos_0_8, "oO9\u00B6");
keyMapping.put(R.id.key_pos_0_9, "pP0\u2206");
keyMapping.put(R.id.key_pos_1_0, "aA@\u00A3");
keyMapping.put(R.id.key_pos_1_1, "sS#\u00A2");
keyMapping.put(R.id.key_pos_1_2, "dD$\u20AC");
keyMapping.put(R.id.key_pos_1_3, "fF_\u00A5");
keyMapping.put(R.id.key_pos_1_4, "gG&\u005E");
keyMapping.put(R.id.key_pos_1_5, "hH-=");
keyMapping.put(R.id.key_pos_1_6, "jJ+{");
keyMapping.put(R.id.key_pos_1_7, "kK(}");
keyMapping.put(R.id.key_pos_1_8, "lL)\\");
keyMapping.put(R.id.key_pos_2_0, "zZ*%");
keyMapping.put(R.id.key_pos_2_1, "xX\"\u00A9");
keyMapping.put(R.id.key_pos_2_2, "cC'\u00AE");
keyMapping.put(R.id.key_pos_2_3, "vV:\u2122");
keyMapping.put(R.id.key_pos_2_4, "bB;\u2713");
keyMapping.put(R.id.key_pos_2_5, "nN![");
keyMapping.put(R.id.key_pos_2_6, "mM?]");
keyMapping.put(R.id.key_pos_bottom_0, ",,,<");
keyMapping.put(R.id.key_pos_bottom_1, "...>");
keyMapping.put(R.id.key_pos_shift, "SHI");
keyMapping.put(R.id.key_pos_del, "DEL");
keyMapping.put(R.id.key_pos_symbol, "SYM");
keyMapping.put(R.id.key_pos_space, "SPA");
keyMapping.put(R.id.key_pos_enter, "ENT");
return new Keyboard(autofillImeService, R.layout.keyboard_10_9_9, keyMapping);
}
View inflateKeyboardView(LayoutInflater inflater, InputView inputView) {
mKeyboardView = inflater.inflate(mViewResId, inputView, false);
mapKeys();
return mKeyboardView;
}
void reset() {
mState = 0;
mapKeys();
}
private void mapKeys() {
for (int i = 0; i < mKeyMapping.size(); i++) {
TextView softkey = mKeyboardView.findViewById(mKeyMapping.keyAt(i));
String rawData = mKeyMapping.valueAt(i);
String data = rawData.length() != NUM_STATES ? rawData : rawData.substring(mState,
mState + 1);
softkey.setText(getLabel(data));
softkey.setOnClickListener(v -> handle(data));
}
}
private void handle(String data) {
if ("SHI".equals(data)) {
// Toggle STATE_SHIFT.
mState = mState ^ STATE_SHIFT;
mapKeys();
} else if ("SYM".equals(data)) {
// Toggle STATE_SYMBOL and clear STATE_SHIFT.
mState = (mState ^ STATE_SYMBOL) & ~STATE_SHIFT;
mapKeys();
} else {
mAutofillImeService.handle(data);
}
}
}