Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 deps.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,210 @@
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);

mConverter = new OpenWnnEngineJAJP();
((OpenWnnEngineJAJP) mConverter).setKeyboardType(OpenWnnEngineJAJP.KEYBOARD_QWERTY);
((OpenWnnEngineJAJP) mConverter).setDictionary(OpenWnnEngineJAJP.DIC_LANG_JP);
mConverter.init();

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

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

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_japanese, 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);
}

@Override
public void clear() {
mConverter.init();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public enum Action {
default @Nullable CandidatesResult getCandidates(String aComposingText) { return null; }
default @Nullable String overrideAddText(String aTextBeforeCursor, String aNextText) { return null; }
default @Nullable String overrideBackspace(String aTextBeforeCursor) { return null; }
default @Nullable CandidatesResult getEmojiCandidates(String aComposingText) { return null; }
default boolean supportsAutoCompletion() { return false; }
default boolean usesComposingText() { return false; }
default boolean usesTextOverride() { return false; }
Expand All @@ -43,4 +44,5 @@ public enum Action {
String getSpaceKeyText(String aComposingText);
String getEnterKeyText(int aIMEOptions, String aComposingText);
String getModeChangeKeyText();
default @Nullable void clear() {}
}
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.KoreanKeyboard;
Expand Down Expand Up @@ -139,6 +140,7 @@ private void initialize(Context aContext) {
mKeyboards.add(new ChinesePinyinKeyboard(aContext));
mKeyboards.add(new ChineseZhuyinKeyboard(aContext));
mKeyboards.add(new KoreanKeyboard(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 @@ -278,6 +280,7 @@ public void updateFocusedView(View aFocusedView) {
mWidgetManager.updateWidget(this);
}

mCurrentKeyboard.clear();
updateCandidates();
updateSpecialKeyLabels();
}
Expand Down Expand Up @@ -391,6 +394,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 @@ -579,6 +585,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 Expand Up @@ -949,6 +961,7 @@ public void afterTextChanged(Editable aEditable) {
if (!mInternalDeleteHint && mCurrentKeyboard.usesComposingText() && mComposingText.length() > 0 && mTextBefore.length() > 0 && aEditable.toString().length() == 0) {
// Text has been cleared externally (e.g. URLBar text clear button)
mComposingText = "";
mCurrentKeyboard.clear();
updateCandidates();
}
mInternalDeleteHint = false;
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