Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Implement Japanese keyboard #974
Browse files Browse the repository at this point in the history
wip


cleanup


wip


wip


wip


wip
  • Loading branch information
keianhzo committed Jun 11, 2019
1 parent 1ed4033 commit ba5d966
Show file tree
Hide file tree
Showing 64 changed files with 99,230 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ infer-out/
fastlane/

app/.externalNativeBuild
openwnn/.externalNativeBuild

*.swp

Expand Down
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ repositories {

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(path: ':openwnn')

// Common
// implementation deps.google_vr.sdk_audio
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class CustomKeyboard extends Keyboard {
public static final int KEYCODE_SYMBOLS_CHANGE = -10;
public static final int KEYCODE_VOICE_INPUT = -11;
public static final int KEYCODE_LANGUAGE_CHANGE = -12;
public static final int KEYCODE_EMOJI = -13;

public CustomKeyboard(Context context, int xmlLayoutResId) {
super(context, xmlLayoutResId, 0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package org.mozilla.vrbrowser.ui.keyboards;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.mozilla.vrbrowser.R;
import org.mozilla.vrbrowser.input.CustomKeyboard;
import org.mozilla.vrbrowser.utils.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import jp.co.omronsoft.openwnn.ComposingText;
import jp.co.omronsoft.openwnn.JAJP.OpenWnnEngineJAJP;
import jp.co.omronsoft.openwnn.JAJP.Romkan;
import jp.co.omronsoft.openwnn.LetterConverter;
import jp.co.omronsoft.openwnn.StrSegment;
import jp.co.omronsoft.openwnn.SymbolList;
import jp.co.omronsoft.openwnn.WnnEngine;
import jp.co.omronsoft.openwnn.WnnWord;

public class JapaneseKeyboard extends BaseKeyboard {

private static final String LOGTAG = "VRB";

private CustomKeyboard mKeyboard;
private CustomKeyboard mSymbolsKeyboard;
private List<Character> mAutocompleteEndings = Arrays.asList(
' ', '、', '。','!','?','ー'
);

private SymbolList mSymbolsConverter;

/** OpenWnn dictionary */
private WnnEngine mConverter;

/** Pre-converter (for Romaji-to-Kana input, Hangul input, etc.) */
protected LetterConverter mPreConverter;

/** The inputing/editing string */
protected ComposingText mComposingText;


public JapaneseKeyboard(Context aContext) {
super(aContext);
}

@NonNull
@Override
public CustomKeyboard getAlphabeticKeyboard() {
if (mKeyboard == null) {
mKeyboard = new CustomKeyboard(mContext.getApplicationContext(), R.xml.keyboard_qwerty_japanese);

mConverter = new OpenWnnEngineJAJP();
mConverter.init();

mPreConverter = new Romkan();
mComposingText = new ComposingText();
}
return mKeyboard;
}

@Nullable
@Override
public CustomKeyboard getSymbolsKeyboard() {
if (mSymbolsKeyboard == null) {
mSymbolsKeyboard = new CustomKeyboard(mContext.getApplicationContext(), R.xml.keyboard_symbols_japanese);

mSymbolsConverter = new SymbolList(mContext, SymbolList.LANG_JA);
}
return mSymbolsKeyboard;
}

@Nullable
@Override
public CandidatesResult getCandidates(String aComposingText) {
if (StringUtils.isEmpty(aComposingText)) {
mComposingText.clear();
return null;
}

// Autocomplete when special characters are clicked
char lastChar = aComposingText.charAt(aComposingText.length() - 1);
boolean autocompose = mAutocompleteEndings.indexOf(lastChar) >= 0;

aComposingText = aComposingText.replaceAll("\\s","");
if (aComposingText.isEmpty()) {
return null;
}

initializeComposingText(aComposingText);

List<Words> words = new ArrayList<>();
int candidates = mConverter.predict(mComposingText, 0, -1);
if (candidates > 0) {
WnnWord word;
while ((word = mConverter.getNextCandidate()) != null) {
words.add(new Words(1, word.stroke, word.candidate));
}
}

CandidatesResult result = new CandidatesResult();
result.words = words;

if (autocompose) {
result.action = CandidatesResult.Action.AUTO_COMPOSE;
result.composing = aComposingText;

mComposingText.clear();

} else {
result.action = CandidatesResult.Action.SHOW_CANDIDATES;
result.composing = mComposingText.toString(ComposingText.LAYER2);
}

return result;
}

@Override
public CandidatesResult getEmojiCandidates(String aComposingText) {
ComposingText text = new ComposingText();
mSymbolsConverter.convert(text);

List<Words> words = new ArrayList<>();
int candidates = mSymbolsConverter.predict(mComposingText, 0, -1);
if (candidates > 0) {
WnnWord word;
while ((word = mSymbolsConverter.getNextCandidate()) != null) {
words.add(new Words(1, word.stroke, word.candidate));
}
}

CandidatesResult result = new CandidatesResult();
result.words = words;
result.action = CandidatesResult.Action.SHOW_CANDIDATES;
result.composing = aComposingText;

return result;
}

@Override
public String getComposingText(String aComposing, String aCode) {
return "";
}

private void initializeComposingText(String text) {
mComposingText.clear();
for (int i=0; i<text.length(); i++) {
mComposingText.insertStrSegment(ComposingText.LAYER0, ComposingText.LAYER1, new StrSegment(text.substring(i, i+1)));
mPreConverter.convert(mComposingText);
}
mComposingText.debugout();
}

@Override
public boolean supportsAutoCompletion() {
return true;
}

@Override
public boolean usesComposingText() {
return true;
}

@Override
public String getKeyboardTitle() {
return StringUtils.getStringByLocale(mContext, R.string.settings_language_traditional_chinese, getLocale());
}

@Override
public Locale getLocale() {
return Locale.JAPAN;
}

@Override
public String getSpaceKeyText(String aComposingText) {
if (aComposingText == null || aComposingText.trim().isEmpty()) {
return mContext.getString(R.string.japanese_spacebar_space);
} else {
return mContext.getString(R.string.japanese_spacebar_selection);
}
}

@Override
public String getEnterKeyText(int aIMEOptions, String aComposingText) {
if (aComposingText == null || aComposingText.trim().isEmpty()) {
return super.getEnterKeyText(aIMEOptions, aComposingText);
} else {
return mContext.getString(R.string.japanese_enter_completion);
}
}

@Override
public String getModeChangeKeyText() {
return mContext.getString(R.string.japanese_keyboard_mode_change);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public enum Action {
float getAlphabeticKeyboardWidth();
default @Nullable CustomKeyboard getSymbolsKeyboard() { return null; }
default @Nullable CandidatesResult getCandidates(String aComposingText) { return null; }
default @Nullable CandidatesResult getEmojiCandidates(String aComposingText) { return null; }
default boolean supportsAutoCompletion() { return false; }
default boolean usesComposingText() { return false; }
String getComposingText(String aComposing, String aCode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.mozilla.vrbrowser.ui.keyboards.FrenchKeyboard;
import org.mozilla.vrbrowser.ui.keyboards.GermanKeyboard;
import org.mozilla.vrbrowser.ui.keyboards.ChineseZhuyinKeyboard;
import org.mozilla.vrbrowser.ui.keyboards.JapaneseKeyboard;
import org.mozilla.vrbrowser.ui.keyboards.KeyboardInterface;
import org.mozilla.vrbrowser.ui.keyboards.RussianKeyboard;
import org.mozilla.vrbrowser.ui.keyboards.SpanishKeyboard;
Expand Down Expand Up @@ -137,6 +138,7 @@ private void initialize(Context aContext) {
mKeyboards.add(new RussianKeyboard(aContext));
mKeyboards.add(new ChinesePinyinKeyboard(aContext));
mKeyboards.add(new ChineseZhuyinKeyboard(aContext));
mKeyboards.add(new JapaneseKeyboard(aContext));

mDefaultKeyboardSymbols = new CustomKeyboard(aContext.getApplicationContext(), R.xml.keyboard_symbols);
mKeyboardNumeric = new CustomKeyboard(aContext.getApplicationContext(), R.xml.keyboard_numeric);
Expand Down Expand Up @@ -389,6 +391,9 @@ public void onKey(int primaryCode, int[] keyCodes, boolean hasPopup) {
case CustomKeyboard.KEYCODE_LANGUAGE_CHANGE:
handleGlobeClick();
break;
case CustomKeyboard.KEYCODE_EMOJI:
handleEmojiInput();
break;
case ' ':
handleSpace();
break;
Expand Down Expand Up @@ -567,6 +572,12 @@ private void handleGlobeClick() {
mPopupKeyboardLayer.setVisibility(View.VISIBLE);
}

private void handleEmojiInput() {
final KeyboardInterface.CandidatesResult candidates = mCurrentKeyboard.getEmojiCandidates(mComposingText);
setAutoCompletionVisible(candidates != null && candidates.words.size() > 0);
mAutoCompletionView.setItems(candidates != null ? candidates.words : null);
}

private void handleLanguageChange(KeyboardInterface aKeyboard) {
cleanComposingText();

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/dimen.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@

<!-- Lang Selector -->
<dimen name="lang_selector_first_col_item_width">100dp</dimen>
<dimen name="lang_selector_second_col_item_width">130dp</dimen>
<dimen name="lang_selector_second_col_item_width">135dp</dimen>

<!-- Common values for menu style widgets -->
<dimen name="menu_item_height">88dp</dimen>
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/non_L10n.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
<string name="zhuyin_enter_completion" translatable="false">選定</string>
<string name="zhuyin_keyboard_mode_change" translatable="false">ㄅㄆㄇ</string>

<string name="japanese_spacebar_selection" translatable="false">次変換</string>
<string name="japanese_spacebar_space" translatable="false">空白</string>
<string name="japanese_enter_completion" translatable="false">確定</string>
<string name="japanese_keyboard_mode_change" translatable="false">かな</string>

<!-- Keyboard -->
<string name="keyboard_popup_a" translatable="false">aáàäãåâąæā</string>
<string name="keyboard_popup_b" translatable="false">bƀḃḅḇ</string>
Expand Down
61 changes: 61 additions & 0 deletions app/src/main/res/xml/keyboard_qwerty_japanese.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:horizontalGap="@dimen/keyboard_horizontal_gap"
android:verticalGap="@dimen/keyboard_vertical_gap"
android:keyWidth="@dimen/keyboard_key_width"
android:keyHeight="@dimen/keyboard_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" />
<Key android:codes="114" android:keyLabel="r" />
<Key android:codes="116" android:keyLabel="t" />
<Key android:codes="121" android:keyLabel="y" />
<Key android:codes="117" android:keyLabel="u" />
<Key android:codes="105" android:keyLabel="i" />
<Key android:codes="111" android:keyLabel="o" />
<Key android:codes="112" android:keyLabel="p" />
<Key android:codes="95" android:keyLabel="_"/>
<Key android:codes="-5" android:keyIcon="@drawable/ic_icon_keyboard_backspace" android:isRepeatable="true" android:keyWidth="@dimen/keyboard_key_backspace_width" />
</Row>

<Row>
<Key android:codes="97" android:keyLabel="a" android:keyEdgeFlags="left" android:horizontalGap="@dimen/keyboard_left_margin" />
<Key android:codes="115" android:keyLabel="s" />
<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" />
<Key android:keyOutputText="" android:keyLabel=""/>
<Key android:codes="-4" android:keyLabel="@string/keyboard_enter_label" android:keyWidth="@dimen/keyboard_key_enter_width" />
</Row>

<Row>
<Key android:codes="-1" android:keyIcon="@drawable/ic_icon_keyboard_shift_off" 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" />
<Key android:codes="109" android:keyLabel="m" />
<Key android:codes="45" android:keyLabel="-" />
<Key android:codes="43" android:keyLabel="+" />
<Key android:codes="47" android:keyLabel="/" />
<Key android:codes="-1" android:keyIcon="@drawable/ic_icon_keyboard_shift_off" />
</Row>

<Row>
<Key android:codes="-2" android:keyLabel="@string/keyboard_symbol" android:keyEdgeFlags="left"/>
<Key android:codes="-12" android:keyIcon="@drawable/ic_icon_keyboard_globe" />
<Key android:codes="32" android:keyLabel="" android:keyWidth="@dimen/keyboard_key_space_width" android:isRepeatable="true"/>
<Key android:keyOutputText="" android:keyLabel=""/>
<Key android:keyOutputText="" android:keyLabel=""/>
<Key android:codes="33" android:keyLabel="!" />
<Key android:codes="63" android:keyLabel="\?" />
<Key android:codes="64" android:keyLabel="\@"/>
</Row>
</Keyboard>
Loading

0 comments on commit ba5d966

Please sign in to comment.