now the Android App has a translation keyboard which allows the translations to be done from inside another application

This commit is contained in:
kr.angelov
2013-11-13 10:45:20 +00:00
parent fa4c327463
commit ab1856046f
31 changed files with 1181 additions and 11 deletions

View File

@@ -25,6 +25,13 @@
</intent-filter>
</activity>
<activity android:name="LexicalEntryActivity"></activity>
<service android:name="TranslatorInputMethodService"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data android:name="android.view.im" android:resource="@xml/method" />
</service>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<org.grammaticalframework.ui.android.TranslatorKeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyboard"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp"
android:layout_margin="1dp"
>
<ImageButton android:id="@+id/closeButton"
android:background="@android:color/transparent"
android:src="@drawable/btn_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="8dp"
android:padding="5dp"
android:clickable="true"
/>
</LinearLayout>

View File

@@ -3,5 +3,8 @@
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="key_height">50dip</dimen>
<dimen name="candidate_font_height">16sp</dimen>
<dimen name="candidate_vertical_padding">6sp</dimen>
</resources>

View File

@@ -9,4 +9,15 @@
<string name="mic_input">Speech Input</string>
<string name="keyboard_input">Keyboard Input</string>
<string name="global_preferences_key">org.grammaticalframework.ui.android.GLOBAL_PREFERENCES</string>
<!-- Labels on soft keys -->
<string name="label_done_key">Done</string>
<string name="label_go_key">Go</string>
<string name="label_next_key">Next</string>
<string name="label_previous_key">Previous</string>
<string name="label_send_key">Send</string>
<!-- Labels for subtype -->
<string name="normalKeyboardMode">normalKeyboardMode</string>
<string name="internalKeyboardMode">internalKeyboardMode</string>
</resources>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="9%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="@dimen/key_height"
>
<Row>
<Key android:codes="1103" android:keyLabel="я" android:keyEdgeFlags="left"/>
<Key android:codes="1074" android:keyLabel="в"/>
<Key android:codes="1077" android:keyLabel="е" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ёєэ"/>
<Key android:codes="1088" android:keyLabel="р"/>
<Key android:codes="1090" android:keyLabel="т" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ћ"/>
<Key android:codes="1098" android:keyLabel="ъ"/>
<Key android:codes="1091" android:keyLabel="у" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ў"/>
<Key android:codes="1080" android:keyLabel="и" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ії"/>
<Key android:codes="1086" android:keyLabel="о"/>
<Key android:codes="1087" android:keyLabel="п"/>
<Key android:codes="1095" android:keyLabel="ч" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ҷҹ" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="1072" android:keyLabel="а" android:keyEdgeFlags="left"/>
<Key android:codes="1089" android:keyLabel="с"/>
<Key android:codes="1076" android:keyLabel="д" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ђ"/>
<Key android:codes="1092" android:keyLabel="ф"/>
<Key android:codes="1075" android:keyLabel="г" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ґѓ"/>
<Key android:codes="1093" android:keyLabel="х"/>
<Key android:codes="1081" android:keyLabel="й" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ј"/>
<Key android:codes="1082" android:keyLabel="к" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ќ"/>
<Key android:codes="1083" android:keyLabel="л" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="љ"/>
<Key android:codes="1096" android:keyLabel="ш"/>
<Key android:codes="1097" android:keyLabel="щ" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
android:keyWidth="14%p" android:isModifier="true"
android:isSticky="true" android:keyEdgeFlags="left"/>
<Key android:codes="1079" android:keyLabel="з"/>
<Key android:codes="1100" android:keyLabel="ь" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ыѣ"/>
<Key android:codes="1094" android:keyLabel="ц"/>
<Key android:codes="1078" android:keyLabel="ж" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="җџ"/>
<Key android:codes="1073" android:keyLabel="б"/>
<Key android:codes="1085" android:keyLabel="н" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="њ"/>
<Key android:codes="1084" android:keyLabel="м"/>
<Key android:codes="1102" android:keyLabel="ю"/>
<Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="15%p" android:keyEdgeFlags="right"
android:isRepeatable="true"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/normalKeyboardMode">
<Key android:codes="-100" android:keyLabel="Sr" android:keyWidth="13%p" android:keyEdgeFlags="left"/>
<Key android:codes="-200" android:keyLabel="Tr" android:keyWidth="13%p"/>
<Key android:codes="-2" android:keyLabel="123" android:keyWidth="13%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:keyWidth="29%p" android:isRepeatable="true"/>
<Key android:codes="46,44" android:keyLabel=". ,"
android:keyWidth="14%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="19%p" android:keyEdgeFlags="right"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/internalKeyboardMode">
<Key android:codes="-2" android:keyLabel="123" android:keyWidth="15%p" android:horizontalGap="10%p" android:keyEdgeFlags="left"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:keyWidth="30%p" android:isRepeatable="true"/>
<Key android:codes="46,44" android:keyLabel=". ,"
android:keyWidth="15%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
</Keyboard>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- The attributes in this XML file provide configuration information -->
<!-- for the Search Manager. -->
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
</input-method>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:keyHeight="10%p">
</Keyboard>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="@dimen/key_height"
>
<Row>
<Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
<Key android:codes="119" android:keyLabel="w"/>
<Key android:codes="101" android:keyLabel="e" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="èéêë"/>
<Key android:codes="114" android:keyLabel="r"/>
<Key android:codes="116" android:keyLabel="t"/>
<Key android:codes="121" android:keyLabel="y" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ýÿ"/>
<Key android:codes="117" android:keyLabel="u" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ùúûü"/>
<Key android:codes="105" android:keyLabel="i" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ìíîï"/>
<Key android:codes="111" android:keyLabel="o" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="òóôõöœø"/>
<Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
android:keyEdgeFlags="left" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="àáâãäåæ"/>
<Key android:codes="115" android:keyLabel="s" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ß"/>
<Key android:codes="100" android:keyLabel="d"/>
<Key android:codes="102" android:keyLabel="f"/>
<Key android:codes="103" android:keyLabel="g"/>
<Key android:codes="104" android:keyLabel="h"/>
<Key android:codes="106" android:keyLabel="j"/>
<Key android:codes="107" android:keyLabel="k"/>
<Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
android:keyWidth="15%p" android:isModifier="true"
android:isSticky="true" android:keyEdgeFlags="left"/>
<Key android:codes="122" android:keyLabel="z"/>
<Key android:codes="120" android:keyLabel="x"/>
<Key android:codes="99" android:keyLabel="c"/>
<Key android:codes="118" android:keyLabel="v"/>
<Key android:codes="98" android:keyLabel="b"/>
<Key android:codes="110" android:keyLabel="n" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ñ"/>
<Key android:codes="109" android:keyLabel="m"/>
<Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="15%p" android:keyEdgeFlags="right"
android:isRepeatable="true"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/normalKeyboardMode">
<Key android:codes="-100" android:keyLabel="Sr" android:keyWidth="13%p" android:keyEdgeFlags="left"/>
<Key android:codes="-200" android:keyLabel="Tr" android:keyWidth="13%p"/>
<Key android:codes="-2" android:keyLabel="123" android:keyWidth="13%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:keyWidth="29%p" android:isRepeatable="true"/>
<Key android:codes="46,44" android:keyLabel=". ,"
android:keyWidth="14%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="19%p" android:keyEdgeFlags="right"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/internalKeyboardMode">
<Key android:codes="-2" android:keyLabel="123" android:keyWidth="15%p" android:horizontalGap="10%p" android:keyEdgeFlags="left"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:keyWidth="30%p" android:isRepeatable="true"/>
<Key android:codes="46,44" android:keyLabel=". ,"
android:keyWidth="15%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
</Keyboard>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="@dimen/key_height"
>
<Row>
<Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
<Key android:codes="50" android:keyLabel="2"/>
<Key android:codes="51" android:keyLabel="3"/>
<Key android:codes="52" android:keyLabel="4"/>
<Key android:codes="53" android:keyLabel="5"/>
<Key android:codes="54" android:keyLabel="6"/>
<Key android:codes="55" android:keyLabel="7"/>
<Key android:codes="56" android:keyLabel="8"/>
<Key android:codes="57" android:keyLabel="9"/>
<Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="64" android:keyLabel="\@" android:keyEdgeFlags="left"/>
<Key android:codes="35" android:keyLabel="\#"/>
<Key android:codes="36" android:keyLabel="$"/>
<Key android:codes="37" android:keyLabel="%"/>
<Key android:codes="38" android:keyLabel="&amp;"/>
<Key android:codes="42" android:keyLabel="*"/>
<Key android:codes="45" android:keyLabel="-"/>
<Key android:codes="61" android:keyLabel="="/>
<Key android:codes="40" android:keyLabel="("/>
<Key android:codes="41" android:keyLabel=")" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
android:keyWidth="15%p" android:isModifier="true"
android:isSticky="true" android:keyEdgeFlags="left"/>
<Key android:codes="33" android:keyLabel="!" />
<Key android:codes="34" android:keyLabel="&quot;"/>
<Key android:codes="39" android:keyLabel="\'"/>
<Key android:codes="58" android:keyLabel=":"/>
<Key android:codes="59" android:keyLabel=";"/>
<Key android:codes="47" android:keyLabel="/" />
<Key android:codes="63" android:keyLabel="\?"/>
<Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="15%p" android:keyEdgeFlags="right"
android:isRepeatable="true"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/normalKeyboardMode">
<Key android:codes="-200" android:keyLabel="Tr" android:horizontalGap="5%p"
android:keyWidth="13%p" android:keyEdgeFlags="left" />
<Key android:codes="-2" android:keyLabel="ABC" android:keyWidth="15%p" />
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" android:keyWidth="30%p"
android:isRepeatable="true"/>
<Key android:codes="44" android:keyLabel="," android:keyWidth="15%p" />
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"
/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/internalKeyboardMode">
<Key android:codes="-2" android:keyLabel="ABC" android:keyWidth="15%p" android:horizontalGap="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" android:keyWidth="30%p"
android:isRepeatable="true"/>
<Key android:codes="44" android:keyLabel="," android:keyWidth="15%p" />
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"
/>
</Row>
</Keyboard>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="@dimen/key_height"
>
<Row>
<Key android:codes="126" android:keyLabel="~" android:keyEdgeFlags="left"/>
<Key android:codes="177" android:keyLabel="±"/>
<Key android:codes="215" android:keyLabel="×"/>
<Key android:codes="247" android:keyLabel="÷"/>
<Key android:codes="8226" android:keyLabel="•"/>
<Key android:codes="176" android:keyLabel="°"/>
<Key android:codes="96" android:keyLabel="`"/>
<Key android:codes="180" android:keyLabel="´"/>
<Key android:codes="123" android:keyLabel="{"/>
<Key android:codes="125" android:keyLabel="}" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="169" android:keyLabel="©" android:keyEdgeFlags="left"/>
<Key android:codes="163" android:keyLabel="£"/>
<Key android:codes="8364" android:keyLabel="€"/>
<Key android:codes="94" android:keyLabel="^"/>
<Key android:codes="174" android:keyLabel="®"/>
<Key android:codes="165" android:keyLabel="¥"/>
<Key android:codes="95" android:keyLabel="_"/>
<Key android:codes="43" android:keyLabel="+"/>
<Key android:codes="91" android:keyLabel="["/>
<Key android:codes="93" android:keyLabel="]" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
android:keyWidth="15%p" android:isModifier="true"
android:isSticky="true" android:keyEdgeFlags="left"/>
<Key android:codes="161" android:keyLabel="¡" />
<Key android:codes="60" android:keyLabel="&lt;"/>
<Key android:codes="62" android:keyLabel="&gt;"/>
<Key android:codes="162" android:keyLabel="¢"/>
<Key android:codes="124" android:keyLabel="|"/>
<Key android:codes="92" android:keyLabel="\\" />
<Key android:codes="191" android:keyLabel="¿"/>
<Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="15%p" android:keyEdgeFlags="right"
android:isRepeatable="true"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/normalKeyboardMode">
<Key android:codes="-200" android:keyLabel="Tr" android:horizontalGap="5%p"
android:keyWidth="13%p" android:keyEdgeFlags="left" />
<Key android:codes="-2" android:keyLabel="ABC" android:keyWidth="15%p" />
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" android:keyWidth="30%p"
android:isRepeatable="true"/>
<Key android:codes="8230" android:keyLabel="…" android:keyWidth="15%p" />
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right" />
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/internalKeyboardMode">
<Key android:codes="-2" android:keyLabel="ABC" android:keyWidth="15%p" android:horizontalGap="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" android:keyWidth="30%p"
android:isRepeatable="true"/>
<Key android:codes="8230" android:keyLabel="…" android:keyWidth="15%p" />
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right" />
</Row>
</Keyboard>

View File

@@ -1,6 +1,7 @@
package org.grammaticalframework.ui.android;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -88,6 +89,9 @@ public class ConversationView extends ScrollView {
return false;
}
});
Bundle extras = edittext.getInputExtras(true);
extras.putBoolean("show_language_toggle", false);
mContent.addView(view);
post(new Runnable() {
public void run() {

View File

@@ -9,12 +9,15 @@ public class Language implements Serializable {
private final String mLangName;
private final String mConcrete;
private final int mInflResource;
private final int mKeyboardResource;
public Language(String langCode, String langName, String concrete, int inflResource) {
public Language(String langCode, String langName, String concrete,
int inflResource, int keyboardResource) {
mLangCode = langCode;
mLangName = langName;
mConcrete = concrete;
mInflResource = inflResource;
mKeyboardResource = keyboardResource;
}
public String getLangCode() {
@@ -28,6 +31,10 @@ public class Language implements Serializable {
public int getInflectionResource() {
return mInflResource;
}
public int getKeyboardResource() {
return mKeyboardResource;
}
String getConcrete() {
return mConcrete;

View File

@@ -45,7 +45,7 @@ public class LexicalEntryActivity extends ListActivity {
mTranslator = ((GFTranslator) getApplicationContext()).getTranslator();
mShowLanguageView = (LanguageSelector) findViewById(R.id.show_language);
mShowLanguageView.setLanguages(mTranslator.getAvailableSourceLanguages());
mShowLanguageView.setLanguages(mTranslator.getAvailableLanguages());
mShowLanguageView.setOnLanguageSelectedListener(new OnLanguageSelectedListener() {
@Override
public void onLanguageSelected(Language language) {

View File

@@ -101,14 +101,14 @@ public class MainActivity extends Activity {
mTranslator = ((GFTranslator) getApplicationContext()).getTranslator();
mSourceLanguageView.setLanguages(mTranslator.getAvailableSourceLanguages());
mSourceLanguageView.setLanguages(mTranslator.getAvailableLanguages());
mSourceLanguageView.setOnLanguageSelectedListener(new OnLanguageSelectedListener() {
@Override
public void onLanguageSelected(Language language) {
onSourceLanguageSelected(language);
}
});
mTargetLanguageView.setLanguages(mTranslator.getAvailableTargetLanguages());
mTargetLanguageView.setLanguages(mTranslator.getAvailableLanguages());
mTargetLanguageView.setOnLanguageSelectedListener(new OnLanguageSelectedListener() {
@Override
public void onLanguageSelected(Language language) {
@@ -192,10 +192,16 @@ public class MainActivity extends Activity {
void onSourceLanguageSelected(Language language) {
mTranslator.setSourceLanguage(language);
if (TranslatorInputMethodService.getInstance() != null) {
TranslatorInputMethodService.getInstance().handleChangeSourceLanguage(language);
}
}
void onTargetLanguageSelected(Language language) {
mTranslator.setTargetLanguage(language);
if (TranslatorInputMethodService.getInstance() != null) {
TranslatorInputMethodService.getInstance().handleChangeTargetLanguage(language);
}
}
public String getSourceLanguageCode() {
@@ -211,6 +217,10 @@ public class MainActivity extends Activity {
Language newTarget = mTranslator.getSourceLanguage();
mSourceLanguageView.setSelectedLanguage(newSource);
mTargetLanguageView.setSelectedLanguage(newTarget);
if (TranslatorInputMethodService.getInstance() != null) {
TranslatorInputMethodService.getInstance().handleSwitchLanguages();
}
}
private void startRecognition() {

View File

@@ -33,8 +33,9 @@ public class Translator {
new Language("fi-FI", "Finnish", "TranslateFin", 0),
new Language("sv-SE", "Swedish", "TranslateSwe", R.xml.inflection_sv),
*/
new Language("en-US", "English", "ParseEng", R.xml.inflection_en),
new Language("bg-BG", "Bulgarian", "ParseBul", R.xml.inflection_bg),
new Language("en-US", "English", "ParseEng", R.xml.inflection_en, R.xml.qwerty),
new Language("bg-BG", "Bulgarian", "ParseBul", R.xml.inflection_bg, R.xml.cyrillic),
new Language("sv-SE", "Swedish", "ParseSwe", R.xml.inflection_sv, R.xml.qwerty),
};
private Language mSourceLanguage;
@@ -78,11 +79,7 @@ public class Translator {
mTargetLanguage = getPrefLang(TARGET_LANG_KEY, 1);
}
public List<Language> getAvailableSourceLanguages() {
return Arrays.asList(mLanguages);
}
public List<Language> getAvailableTargetLanguages() {
public List<Language> getAvailableLanguages() {
return Arrays.asList(mLanguages);
}

View File

@@ -0,0 +1,581 @@
package org.grammaticalframework.ui.android;
import android.inputmethodservice.InputMethodService;
import android.text.InputType;
import android.text.method.MetaKeyKeyListener;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import java.util.ArrayList;
import java.util.List;
public class TranslatorInputMethodService extends InputMethodService
implements android.inputmethodservice.KeyboardView.OnKeyboardActionListener {
private TranslatorKeyboardView mInputView;
private CompletionsView mCandidateView;
private CompletionInfo[] mCompletions;
private StringBuilder mComposing = new StringBuilder();
private boolean mPredictionOn;
private boolean mCompletionOn;
private boolean mCapsLock;
private long mLastShiftTime;
private long mMetaState;
private TranslatorKeyboard mSymbolsKeyboard;
private TranslatorKeyboard mSymbolsShiftedKeyboard;
private TranslatorKeyboard mLanguageKeyboard;
private TranslatorKeyboard mCurKeyboard;
private int mActionId;
private Translator mTranslator;
@Override
public void onCreate() {
super.onCreate();
mTranslator = ((GFTranslator) getApplicationContext()).getTranslator();
mSymbolsKeyboard = null;
mSymbolsShiftedKeyboard = null;
mLanguageKeyboard = null;
}
@Override
public View onCreateInputView() {
mInputView = (TranslatorKeyboardView)
getLayoutInflater().inflate(R.layout.input, null);
mInputView.setOnKeyboardActionListener(this);
mInputView.setKeyboard(mCurKeyboard);
return mInputView;
}
@Override
public View onCreateCandidatesView() {
mCandidateView = new CompletionsView(this);
mCandidateView.setService(this);
return mCandidateView;
}
private int mModeId;
private static TranslatorInputMethodService mInstance;
static TranslatorInputMethodService getInstance() {
return mInstance;
}
@Override
public void onStartInput(EditorInfo attribute, boolean restarting) {
super.onStartInput(attribute, restarting);
// Reset our state. We want to do this even if restarting, because
// the underlying state of the text editor could have changed in any way.
mComposing.setLength(0);
updateCandidates();
if (!restarting) {
// Clear shift states.
mMetaState = 0;
}
mPredictionOn = false;
mCompletionOn = false;
mCompletions = null;
int res =
mTranslator.getSourceLanguage().getKeyboardResource();
mModeId = R.string.normalKeyboardMode;
if (attribute.extras != null &&
!attribute.extras.getBoolean("show_language_toggle", true)) {
mModeId = R.string.internalKeyboardMode;
}
mLanguageKeyboard = new TranslatorKeyboard(this, res, mModeId);
mSymbolsKeyboard = new TranslatorKeyboard(this, R.xml.symbols, mModeId);
mSymbolsShiftedKeyboard = new TranslatorKeyboard(this, R.xml.symbols_shift, mModeId);
// We are now going to initialize our state based on the type of
// text being edited.
switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
case InputType.TYPE_CLASS_NUMBER:
case InputType.TYPE_CLASS_DATETIME:
// Numbers and dates default to the symbols keyboard, with
// no extra features.
mCurKeyboard = mSymbolsKeyboard;
break;
case InputType.TYPE_CLASS_PHONE:
// Phones will also default to the symbols keyboard, though
// often you will want to have a dedicated phone keyboard.
mCurKeyboard = mSymbolsKeyboard;
break;
case InputType.TYPE_CLASS_TEXT:
// This is general text editing. We will default to the
// normal alphabetic keyboard, and assume that we should
// be doing predictive text (showing candidates as the
// user types).
mCurKeyboard = mLanguageKeyboard;
mPredictionOn = true;
// We now look for a few special variations of text that will
// modify our behavior.
int variation = attribute.inputType & InputType.TYPE_MASK_VARIATION;
if (variation == InputType.TYPE_TEXT_VARIATION_PASSWORD ||
variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
// Do not display predictions / what the user is typing
// when they are entering a password.
mPredictionOn = false;
}
if (variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|| variation == InputType.TYPE_TEXT_VARIATION_URI
|| variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
// Our predictions are not useful for e-mail addresses
// or URIs.
mPredictionOn = false;
}
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
// If this is an auto-complete text view, then our predictions
// will not be shown and instead we will allow the editor
// to supply their own. We only show the editor's
// candidates when in full-screen mode, otherwise relying
// own it displaying its own UI.
mPredictionOn = false;
mCompletionOn = isFullscreenMode();
}
// We also want to look at the current state of the editor
// to decide whether our alphabetic keyboard should start out
// shifted.
updateShiftKeyState(attribute);
break;
default:
// For all unknown input types, default to the alphabetic
// keyboard with no special features.
mCurKeyboard = mLanguageKeyboard;
updateShiftKeyState(attribute);
}
mActionId = attribute.imeOptions & EditorInfo.IME_MASK_ACTION;
mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
mInstance = this;
}
@Override
public void onFinishInput() {
super.onFinishInput();
// Clear current composing text and candidates.
mComposing.setLength(0);
updateCandidates();
// We only hide the candidates window when finishing input on
// a particular editor, to avoid popping the underlying application
// up and down if the user is entering text into the bottom of
// its window.
setCandidatesViewShown(false);
mCurKeyboard = mLanguageKeyboard;
if (mInputView != null) {
mInputView.closing();
}
mInstance = null;
}
@Override
public void onStartInputView(EditorInfo attribute, boolean restarting) {
super.onStartInputView(attribute, restarting);
// Apply the selected keyboard to the input view.
mInputView.setKeyboard(mCurKeyboard);
mInputView.closing();
}
@Override
public void onUpdateSelection(int oldSelStart, int oldSelEnd,
int newSelStart, int newSelEnd,
int candidatesStart, int candidatesEnd) {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
candidatesStart, candidatesEnd);
// If the current selection in the text view changes, we should
// clear whatever candidate text we have.
if (mComposing.length() > 0 && (newSelStart != candidatesEnd
|| newSelEnd != candidatesEnd)) {
mComposing.setLength(0);
updateCandidates();
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.finishComposingText();
}
}
}
@Override
public void onDisplayCompletions(CompletionInfo[] completions) {
if (mCompletionOn) {
mCompletions = completions;
if (completions == null) {
setSuggestions(null, false, false);
return;
}
List<String> stringList = new ArrayList<String>();
for (int i = 0; i < completions.length; i++) {
CompletionInfo ci = completions[i];
if (ci != null) stringList.add(ci.getText().toString());
}
setSuggestions(stringList, true, true);
}
}
/**
* This translates incoming hard key events in to edit operations on an
* InputConnection. It is only needed when using the
* PROCESS_HARD_KEYS option.
*/
private boolean translateKeyDown(int keyCode, KeyEvent event) {
mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState,
keyCode, event);
int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(mMetaState));
mMetaState = MetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
InputConnection ic = getCurrentInputConnection();
if (c == 0 || ic == null) {
return false;
}
if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
}
if (mComposing.length() > 0) {
char accent = mComposing.charAt(mComposing.length() -1 );
int composed = KeyEvent.getDeadChar(accent, c);
if (composed != 0) {
c = composed;
mComposing.setLength(mComposing.length()-1);
}
}
onKey(c, null);
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
// The InputMethodService already takes care of the back
// key for us, to dismiss the input method if it is shown.
// However, our keyboard could be showing a pop-up window
// that back should dismiss, so we first allow it to do that.
if (event.getRepeatCount() == 0 && mInputView != null) {
if (mInputView.handleBack()) {
return true;
}
}
break;
case KeyEvent.KEYCODE_DEL:
// Special handling of the delete key: if we currently are
// composing text for the user, we want to modify that instead
// of let the application to the delete itself.
if (mComposing.length() > 0) {
onKey(TranslatorKeyboard.KEYCODE_DELETE, null);
return true;
}
break;
case KeyEvent.KEYCODE_ENTER:
// Let the underlying text editor always handle these.
return false;
default:
if (mPredictionOn && translateKeyDown(keyCode, event)) {
return true;
}
}
return super.onKeyDown(keyCode, event);
}
/**
* Helper function to commit any text being composed in to the editor.
*/
private void commitTyped(InputConnection inputConnection) {
if (mComposing.length() > 0) {
inputConnection.commitText(mComposing, mComposing.length());
mComposing.setLength(0);
updateCandidates();
}
}
/**
* Helper to update the shift state of our keyboard based on the initial
* editor state.
*/
private void updateShiftKeyState(EditorInfo attr) {
if (attr != null
&& mInputView != null && mLanguageKeyboard == mInputView.getKeyboard()) {
int caps = 0;
EditorInfo ei = getCurrentInputEditorInfo();
if (ei != null && ei.inputType != InputType.TYPE_NULL) {
caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
}
mInputView.setShifted(mCapsLock || caps != 0);
}
}
/**
* Helper to send a key down / key up pair to the current editor.
*/
private void keyDownUp(int keyEventCode) {
getCurrentInputConnection().sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
getCurrentInputConnection().sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
}
// Implementation of KeyboardViewListener
public void onKey(int primaryCode, int[] keyCodes) {
if (primaryCode == TranslatorKeyboard.KEYCODE_DELETE) {
handleBackspace();
} else if (primaryCode == TranslatorKeyboard.KEYCODE_SHIFT) {
handleShift();
} else if (primaryCode == TranslatorKeyboard.KEYCODE_SOURCE_LANGUAGE
&& mInputView != null) {
Language newSource = mTranslator.getTargetLanguage();
Language newTarget = mTranslator.getSourceLanguage();
mTranslator.setSourceLanguage(newSource);
mTranslator.setTargetLanguage(newTarget);
handleSwitchLanguages();
} else if (primaryCode < TranslatorKeyboard.KEYCODE_SOURCE_LANGUAGE &&
primaryCode > TranslatorKeyboard.KEYCODE_SOURCE_LANGUAGE-TranslatorKeyboard.MAX_LANGUAGE_KEYCODES) {
Language newSource =
mTranslator.getAvailableLanguages().get(TranslatorKeyboard.KEYCODE_SOURCE_LANGUAGE-primaryCode-1);
mTranslator.setSourceLanguage(newSource);
handleChangeSourceLanguage(newSource);
} else if (primaryCode == TranslatorKeyboard.KEYCODE_TARGET_LANGUAGE) {
String translation = mTranslator.translate(mComposing.toString());
getCurrentInputConnection().commitText(translation, 1);
return;
} else if (primaryCode < TranslatorKeyboard.KEYCODE_TARGET_LANGUAGE &&
primaryCode > TranslatorKeyboard.KEYCODE_TARGET_LANGUAGE-TranslatorKeyboard.MAX_LANGUAGE_KEYCODES) {
Language newTarget =
mTranslator.getAvailableLanguages().get(TranslatorKeyboard.KEYCODE_TARGET_LANGUAGE-primaryCode-1);
mTranslator.setTargetLanguage(newTarget);
handleChangeTargetLanguage(newTarget);
} else if (primaryCode == TranslatorKeyboard.KEYCODE_MODE_CHANGE
&& mInputView != null) {
TranslatorKeyboard current = (TranslatorKeyboard) mInputView.getKeyboard();
if (current == mSymbolsKeyboard || current == mSymbolsShiftedKeyboard) {
current = mLanguageKeyboard;
} else {
current = mSymbolsKeyboard;
}
mInputView.setKeyboard(current);
if (current == mSymbolsKeyboard) {
current.setShifted(false);
}
} else if (primaryCode == 10) {
getCurrentInputConnection().performEditorAction(mActionId);
} else if (primaryCode == ' ' && mComposing.length() == 0) {
getCurrentInputConnection().commitText(" ", 1);
} else {
handleCharacter(primaryCode, keyCodes);
}
}
public void onText(CharSequence text) {
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
if (mComposing.length() > 0) {
commitTyped(ic);
}
ic.commitText(text, 0);
ic.endBatchEdit();
updateShiftKeyState(getCurrentInputEditorInfo());
}
/**
* Update the list of available candidates from the current composing
* text. This will need to be filled in by however you are determining
* candidates.
*/
private void updateCandidates() {
if (!mCompletionOn) {
if (mComposing.length() > 0) {
ArrayList<String> list = new ArrayList<String>();
list.add(mComposing.toString());
list.add("alfa");
list.add("beta");
setSuggestions(list, true, true);
Log.d("KEYBOARD", mComposing.toString());
} else {
setSuggestions(null, false, false);
}
}
}
public void setSuggestions(List<String> suggestions, boolean completions,
boolean typedWordValid) {
if (suggestions != null && suggestions.size() > 0) {
setCandidatesViewShown(true);
} else if (isExtractViewShown()) {
setCandidatesViewShown(true);
}
if (mCandidateView != null) {
mCandidateView.setSuggestions(suggestions, completions, typedWordValid);
}
}
private void handleBackspace() {
final int length = mComposing.length();
if (length > 1) {
mComposing.delete(length - 1, length);
getCurrentInputConnection().setComposingText(mComposing, 1);
updateCandidates();
} else if (length > 0) {
mComposing.setLength(0);
getCurrentInputConnection().commitText("", 0);
updateCandidates();
} else {
keyDownUp(KeyEvent.KEYCODE_DEL);
}
updateShiftKeyState(getCurrentInputEditorInfo());
}
private void handleShift() {
if (mInputView == null) {
return;
}
TranslatorKeyboard currentKeyboard = (TranslatorKeyboard) mInputView.getKeyboard();
if (mLanguageKeyboard == currentKeyboard) {
// Alphabet keyboard
checkToggleCapsLock();
mInputView.setShifted(mCapsLock || !mInputView.isShifted());
} else if (currentKeyboard == mSymbolsKeyboard) {
mSymbolsKeyboard.setShifted(true);
mInputView.setKeyboard(mSymbolsShiftedKeyboard);
mSymbolsShiftedKeyboard.setShifted(true);
} else if (currentKeyboard == mSymbolsShiftedKeyboard) {
mSymbolsShiftedKeyboard.setShifted(false);
mInputView.setKeyboard(mSymbolsKeyboard);
mSymbolsKeyboard.setShifted(false);
}
}
private void handleCharacter(int primaryCode, int[] keyCodes) {
if (isInputViewShown()) {
if (mInputView.isShifted()) {
primaryCode = Character.toUpperCase(primaryCode);
}
}
mComposing.append((char) primaryCode);
getCurrentInputConnection().setComposingText(mComposing, 1);
updateShiftKeyState(getCurrentInputEditorInfo());
if (mPredictionOn) {
updateCandidates();
}
}
private void handleClose() {
commitTyped(getCurrentInputConnection());
requestHideSelf(0);
mInputView.closing();
}
void handleChangeSourceLanguage(Language newSource) {
mLanguageKeyboard =
new TranslatorKeyboard(this, newSource.getKeyboardResource(), mModeId);
mSymbolsKeyboard.updateLanguageKeyLabels();
mSymbolsShiftedKeyboard.updateLanguageKeyLabels();
mInputView.setKeyboard(mLanguageKeyboard);
}
void handleChangeTargetLanguage(Language newTarget) {
mLanguageKeyboard.updateLanguageKeyLabels();
mSymbolsKeyboard.updateLanguageKeyLabels();
mSymbolsShiftedKeyboard.updateLanguageKeyLabels();
mInputView.invalidateAllKeys();
}
void handleSwitchLanguages() {
Language newSource = mTranslator.getSourceLanguage();
mLanguageKeyboard =
new TranslatorKeyboard(this, newSource.getKeyboardResource(), mModeId);
mInputView.setKeyboard(mLanguageKeyboard);
}
private void checkToggleCapsLock() {
long now = System.currentTimeMillis();
if (mLastShiftTime + 800 > now) {
mCapsLock = !mCapsLock;
mLastShiftTime = 0;
} else {
mLastShiftTime = now;
}
}
public void pickDefaultCandidate() {
pickSuggestionManually(0);
}
public void pickSuggestionManually(int index) {
if (mCompletionOn && mCompletions != null && index >= 0
&& index < mCompletions.length) {
CompletionInfo ci = mCompletions[index];
getCurrentInputConnection().commitCompletion(ci);
if (mCandidateView != null) {
mCandidateView.clear();
}
updateShiftKeyState(getCurrentInputEditorInfo());
} else if (mComposing.length() > 0) {
// If we were generating candidate suggestions for the current
// text, we would commit one of them here. But for this sample,
// we will just commit the current text.
commitTyped(getCurrentInputConnection());
}
}
public void swipeRight() {
if (mCompletionOn) {
pickDefaultCandidate();
}
}
public void swipeLeft() {
handleBackspace();
}
public void swipeDown() {
handleClose();
}
public void swipeUp() {
}
public void onPress(int primaryCode) {
}
public void onRelease(int primaryCode) {
}
}

View File

@@ -0,0 +1,103 @@
package org.grammaticalframework.ui.android;
import java.util.Locale;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.view.inputmethod.EditorInfo;
import android.inputmethodservice.Keyboard;
public class TranslatorKeyboard extends Keyboard {
private Key mEnterKey;
private Key mSourceLanguageKey;
private Key mTargetLanguageKey;
static final int KEYCODE_SOURCE_LANGUAGE = -100;
static final int KEYCODE_TARGET_LANGUAGE = -200;
static final int MAX_LANGUAGE_KEYCODES = 99;
private Translator mTranslator;
public TranslatorKeyboard(Context context, int xmlLayoutResId, int modeId) {
super(context, xmlLayoutResId, modeId);
mTranslator = ((GFTranslator) context.getApplicationContext()).getTranslator();
updateLanguageKeyLabels();
}
public void updateLanguageKeyLabels() {
if (mSourceLanguageKey != null)
mSourceLanguageKey.label = getLanguageKeyLabel(mTranslator.getSourceLanguage());
if (mTargetLanguageKey != null)
mTargetLanguageKey.label = getLanguageKeyLabel(mTranslator.getTargetLanguage());
}
public static String getLanguageKeyLabel(Language lang) {
return
LocaleUtils.parseJavaLocale(lang.getLangCode(), Locale.getDefault())
.getISO3Language();
}
@Override
protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
XmlResourceParser parser) {
Key key = new Key(res, parent, x, y, parser);
if (key.codes[0] == 10) {
mEnterKey = key;
} else if (key.codes[0] == KEYCODE_SOURCE_LANGUAGE) {
mSourceLanguageKey = key;
} else if (key.codes[0] == KEYCODE_TARGET_LANGUAGE) {
mTargetLanguageKey = key;
}
return key;
}
/**
* This looks at the ime options given by the current editor, to set the
* appropriate label on the keyboard's enter key (if it has one).
*/
void setImeOptions(Resources res, int options) {
if (mEnterKey == null) {
return;
}
switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) {
case EditorInfo.IME_ACTION_DONE:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_done_key);
break;
case EditorInfo.IME_ACTION_GO:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_go_key);
break;
case EditorInfo.IME_ACTION_NEXT:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_next_key);
break;
case EditorInfo.IME_ACTION_PREVIOUS:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_previous_key);
break;
case EditorInfo.IME_ACTION_SEARCH:
mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search);
mEnterKey.label = null;
break;
case EditorInfo.IME_ACTION_SEND:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_send_key);
break;
default:
mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_return);
mEnterKey.label = null;
break;
}
}
}

View File

@@ -0,0 +1,113 @@
package org.grammaticalframework.ui.android;
import java.util.Locale;
import org.grammaticalframework.ui.android.TranslatorKeyboard;
import android.content.Context;
import android.inputmethodservice.Keyboard.Key;
import android.inputmethodservice.KeyboardView;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
public class TranslatorKeyboardView extends KeyboardView {
private Translator mTranslator;
public TranslatorKeyboardView(Context context, AttributeSet attrs) {
super(context, attrs);
mTranslator = ((GFTranslator) context.getApplicationContext()).getTranslator();
}
public TranslatorKeyboardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mTranslator = ((GFTranslator) context.getApplicationContext()).getTranslator();
}
private PopupWindow mLanguagesPopup = null;
private Key mLanguagesKey = null;
private void showLanguageOptions(Key popupKey) {
if (mLanguagesPopup == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
LinearLayout popupContainer = (LinearLayout)
inflater.inflate(R.layout.keyboard_languages_options, null);
int index = 0;
for (Language lang : mTranslator.getAvailableLanguages()) {
Button item = new Button(getContext());
item.setText(TranslatorKeyboard.getLanguageKeyLabel(lang));
item.setTag(index);
item.setOnClickListener(this);
popupContainer.addView(item, index++);
}
popupContainer.measure(
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
mLanguagesPopup = new PopupWindow(getContext());
mLanguagesPopup.setWidth(popupContainer.getMeasuredWidth());
mLanguagesPopup.setHeight(popupContainer.getMeasuredHeight());
mLanguagesPopup.setContentView(popupContainer);
int[] windowOffset = new int[2];
getLocationInWindow(windowOffset);
int popupX = popupKey.x + popupKey.width - popupContainer.getMeasuredWidth();
int popupY = popupKey.y - popupContainer.getMeasuredHeight();
final int x = popupX + popupContainer.getPaddingRight() + windowOffset[0];
final int y = popupY + popupContainer.getPaddingBottom() + windowOffset[1];
mLanguagesPopup.showAtLocation(this, Gravity.NO_GRAVITY, x, y);
View closeButton = popupContainer.findViewById(R.id.closeButton);
if (closeButton != null) closeButton.setOnClickListener(this);
}
mLanguagesKey = popupKey;
}
private void dismissLanguages() {
if (mLanguagesPopup != null) {
mLanguagesPopup.dismiss();
mLanguagesPopup = null;
mLanguagesKey = null;
}
}
@Override
public void onClick(View v) {
super.onClick(v);
if (v.getTag() != null) {
if (mLanguagesKey.codes[0] == TranslatorKeyboard.KEYCODE_SOURCE_LANGUAGE ||
mLanguagesKey.codes[0] == TranslatorKeyboard.KEYCODE_TARGET_LANGUAGE) {
int keyCode = mLanguagesKey.codes[0] - ((Integer) v.getTag()) - 1;
getOnKeyboardActionListener().onKey(keyCode, new int[] {keyCode});
}
}
dismissLanguages();
}
public void closing() {
super.closing();
dismissLanguages();
}
@Override
protected boolean onLongPress(Key key) {
if (key.codes[0] == TranslatorKeyboard.KEYCODE_SOURCE_LANGUAGE ||
key.codes[0] == TranslatorKeyboard.KEYCODE_TARGET_LANGUAGE) {
showLanguageOptions(key);
return true;
} else {
return super.onLongPress(key);
}
}
}