Skip to content

Commit 521369b

Browse files
committed
Merge branch 'AquiTCD-feature/keybind-customization'
2 parents 67dffc2 + f3f202b commit 521369b

10 files changed

Lines changed: 168 additions & 65 deletions

File tree

app/src/androidTest/java/jp/deadend/noname/skk/SKKSettingsActivityUITest.kt

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,62 @@ class SKKSettingsActivityUITest {
201201
fun testHardKeyFragment() {
202202
assert(skkPrefs.kanaKey == KeyEvent.KEYCODE_J shl 4 or /* CTRL_PRESSED */ 4)
203203
onView(withText("ハードウェアキーボードの設定")).perform(click())
204+
205+
// かなキー (CTRL+J -> TAB)
204206
onView(withText("かなキー"))
205207
.check(matches(hasSibling(withText("CTRL+J"))))
206208
.perform(click())
207209
.check(matches(hasSibling(withText("Push any key..."))))
208-
repeat(3) { // ときどき key up しか発行されないことがある?
210+
repeat(3) {
209211
Thread.sleep(1000)
210212
onView(withText("かなキー")).perform(pressKey(KeyEvent.KEYCODE_TAB))
211213
}
212-
onView(withText("かなキー"))
213-
.check(matches(hasSibling(withText("TAB"))))
214+
onView(withText("かなキー")).check(matches(hasSibling(withText("TAB"))))
214215
assert(skkPrefs.kanaKey == KeyEvent.KEYCODE_TAB shl 4)
216+
217+
// カタカナキー (Q -> T)
218+
onView(withText("カタカナキー"))
219+
.check(matches(hasSibling(withText("Q"))))
220+
.perform(click())
221+
repeat(3) {
222+
Thread.sleep(1000)
223+
onView(withText("カタカナキー")).perform(pressKey(KeyEvent.KEYCODE_T))
224+
}
225+
onView(withText("カタカナキー")).check(matches(hasSibling(withText("T"))))
226+
assert(skkPrefs.katakanaKey == KeyEvent.KEYCODE_T shl 4)
227+
228+
// ASCIIキー (L -> A)
229+
onView(withText("ASCIIキー"))
230+
.check(matches(hasSibling(withText("L"))))
231+
.perform(click())
232+
repeat(3) {
233+
Thread.sleep(1000)
234+
onView(withText("ASCIIキー")).perform(pressKey(KeyEvent.KEYCODE_A))
235+
}
236+
onView(withText("ASCIIキー")).check(matches(hasSibling(withText("A"))))
237+
assert(skkPrefs.asciiKey == KeyEvent.KEYCODE_A shl 4)
238+
239+
// 全角英数キー (SHIFT+L -> SHIFT+Z)
240+
onView(withText("全角英数キー"))
241+
.check(matches(hasSibling(withText("SHIFT+L"))))
242+
.perform(click())
243+
repeat(3) {
244+
Thread.sleep(1000)
245+
onView(withText("全角英数キー")).perform(pressKey(KeyEvent.KEYCODE_Z, KeyEvent.META_SHIFT_LEFT_ON))
246+
}
247+
onView(withText("全角英数キー")).check(matches(hasSibling(withText("SHIFT+Z"))))
248+
assert(skkPrefs.zenkakuKey == (KeyEvent.KEYCODE_Z shl 4 or 1))
249+
250+
// Abbrevキー (SLASH -> PERIOD)
251+
onView(withText("Abbrevキー"))
252+
.check(matches(hasSibling(withText("SLASH"))))
253+
.perform(click())
254+
repeat(3) {
255+
Thread.sleep(1000)
256+
onView(withText("Abbrevキー")).perform(pressKey(KeyEvent.KEYCODE_PERIOD))
257+
}
258+
onView(withText("Abbrevキー")).check(matches(hasSibling(withText("PERIOD"))))
259+
assert(skkPrefs.abbrevKey == (KeyEvent.KEYCODE_PERIOD shl 4))
215260
}
216261

217262
@Test

app/src/main/java/jp/deadend/noname/skk/SKKPrefs.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ class SKKPrefs(context: Context) {
7070
get() = prefs.getInt(res.getString(R.string.pref_cancel_key), 564) // 564はCtrl+g
7171
set(value) = prefs.edit { putInt(res.getString(R.string.pref_cancel_key), value) }
7272

73+
var katakanaKey: Int
74+
get() = prefs.getInt(res.getString(R.string.pref_katakana_key), 720) // 720はq (KEYCODE_Q=45, shl 4)
75+
set(value) = prefs.edit { putInt(res.getString(R.string.pref_katakana_key), value) }
76+
77+
var asciiKey: Int
78+
get() = prefs.getInt(res.getString(R.string.pref_ascii_key), 640) // 640はl (KEYCODE_L=40, shl 4)
79+
set(value) = prefs.edit { putInt(res.getString(R.string.pref_ascii_key), value) }
80+
81+
var zenkakuKey: Int
82+
get() = prefs.getInt(res.getString(R.string.pref_zenkaku_key), 641) // 641はShift+L (40 shl 4 | 1)
83+
set(value) = prefs.edit { putInt(res.getString(R.string.pref_zenkaku_key), value) }
84+
85+
var abbrevKey: Int
86+
get() = prefs.getInt(res.getString(R.string.pref_abbrev_key), 1216) // 1216はSlash (KEYCODE_SLASH=76, shl 4)
87+
set(value) = prefs.edit { putInt(res.getString(R.string.pref_abbrev_key), value) }
88+
7389
var useCandidatesView: Boolean
7490
get() = prefs.getBoolean(res.getString(R.string.pref_use_candidates_view), true)
7591
set(value) = prefs.edit {

app/src/main/java/jp/deadend/noname/skk/SKKService.kt

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ class SKKService : InputMethodService() {
681681

682682
// テンキーにする
683683
"flick-num" -> {
684-
mEngine.changeInputMode('l'.code)
684+
mEngine.handleASCIIKey()
685685
mFlickJPInputView?.let {
686686
setInputView(it) // Godan ユーザにも FlickJP のテンキーを強制
687687
it.keyboard = it.mNumKeyboard
@@ -690,15 +690,15 @@ class SKKService : InputMethodService() {
690690

691691
// 英字にする
692692
"qwerty" -> {
693-
mEngine.changeInputMode('l'.code)
693+
mEngine.handleASCIIKey()
694694
if (mInputView?.equals(mQwertyInputView) == true) {
695695
mQwertyInputView!!.keyboard = mQwertyInputView!!.mLatinKeyboard
696696
}
697697
}
698698

699699
// 英数記号にする
700700
"symbols" -> {
701-
mEngine.changeInputMode('l'.code)
701+
mEngine.handleASCIIKey()
702702
if (mInputView?.equals(mQwertyInputView) == true) {
703703
mQwertyInputView!!.keyboard = mQwertyInputView!!.mSymbolsKeyboard
704704
}
@@ -920,6 +920,11 @@ class SKKService : InputMethodService() {
920920
return true
921921
}
922922

923+
if (encodedKey == skkPrefs.katakanaKey) {
924+
mEngine.handleKatakanaKey()
925+
return true
926+
}
927+
923928
if (engineState === SKKASCIIState && !mEngine.isRegistering) {
924929
val result = super.onKeyDown(keyCode, event)
925930
updateSuggestionsASCII()
@@ -930,6 +935,20 @@ class SKKService : InputMethodService() {
930935
if (handleCancel()) return true
931936
}
932937

938+
if (encodedKey == skkPrefs.asciiKey) {
939+
mEngine.handleASCIIKey()
940+
return true
941+
}
942+
943+
if (encodedKey == skkPrefs.zenkakuKey) {
944+
mEngine.handleZenkakuKey()
945+
return true
946+
}
947+
948+
if (encodedKey == skkPrefs.abbrevKey) {
949+
if (mEngine.tryStartAbbrev()) return true
950+
}
951+
933952
if (encodedKey == 724) { // Ctrl-Q
934953
processKey(17) // 基本的には半角カナだがAbbrevでは全角への変換となる
935954
return true

app/src/main/java/jp/deadend/noname/skk/SKKSettingsActivity.kt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,19 @@ class SKKSettingsActivity : AppCompatActivity() {
7474
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
7575
setPreferencesFromResource(R.xml.prefs_hard_key, rootKey)
7676

77-
findPreference<Preference>(getString(R.string.pref_kana_key))?.apply {
78-
setSummary(getKeyName(skkPrefs.kanaKey))
79-
setOnPreferenceClickListener {
80-
setSummary("Push any key...")
81-
(requireActivity() as SKKSettingsActivity).keyPref = this
82-
true
83-
}
84-
}
77+
registerKeyPref(R.string.pref_kana_key, skkPrefs.kanaKey)
78+
registerKeyPref(R.string.pref_cancel_key, skkPrefs.cancelKey)
79+
registerKeyPref(R.string.pref_katakana_key, skkPrefs.katakanaKey)
80+
registerKeyPref(R.string.pref_ascii_key, skkPrefs.asciiKey)
81+
registerKeyPref(R.string.pref_zenkaku_key, skkPrefs.zenkakuKey)
82+
registerKeyPref(R.string.pref_abbrev_key, skkPrefs.abbrevKey)
83+
}
8584

86-
findPreference<Preference>(getString(R.string.pref_cancel_key))?.apply {
87-
setSummary(getKeyName(skkPrefs.cancelKey))
85+
private fun registerKeyPref(prefKeyResId: Int, currentValue: Int) {
86+
findPreference<Preference>(getString(prefKeyResId))?.apply {
87+
summary = getKeyName(currentValue)
8888
setOnPreferenceClickListener {
89-
setSummary("Push any key...")
89+
summary = "Push any key..."
9090
(requireActivity() as SKKSettingsActivity).keyPref = this
9191
true
9292
}

app/src/main/java/jp/deadend/noname/skk/engine/RomajiConverter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,4 @@ object RomajiConverter {
172172
}
173173

174174
fun isIntermediateRomaji(composing: String): Boolean = (composing in mIntermediateRomajiSet)
175-
}
175+
}

app/src/main/java/jp/deadend/noname/skk/engine/SKKEngine.kt

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,52 @@ class SKKEngine(
138138
fun processKey(keyCode: Int) = state.processKey(this, keyCode)
139139

140140
fun handleKanaKey() = state.handleKanaKey(this)
141+
142+
fun handleKatakanaKey() {
143+
when (state) {
144+
SKKHiraganaState -> changeState(SKKKatakanaState)
145+
SKKKatakanaState -> changeState(SKKHiraganaState)
146+
SKKKanjiState -> {
147+
// ▽モードでカタカナ変換(従来の q 動作を引き継ぐ)
148+
if (mKanjiKey.isNotEmpty()) {
149+
val str = if (kanaState == SKKHiraganaState) {
150+
hiragana2katakana(mKanjiKey.toString())
151+
} else {
152+
mKanjiKey.toString()
153+
}
154+
if (str != null) commitTextSKK(str)
155+
mKanjiKey.setLength(0)
156+
}
157+
changeState(kanaState)
158+
}
159+
160+
else -> {}
161+
}
162+
}
163+
164+
fun handleASCIIKey() {
165+
if (mComposing.length != 1 || mComposing[0] != 'z') {
166+
// ▽モード(KanjiState)では l で Abbrev モードに遷移(SKK 原本の動作)
167+
if (state === SKKKanjiState) {
168+
changeState(SKKAbbrevState)
169+
} else {
170+
changeState(SKKASCIIState, true)
171+
}
172+
}
173+
// 「→」を入力するための z+l 例外はそのまま維持
174+
}
175+
176+
fun handleZenkakuKey() {
177+
changeState(SKKZenkakuState)
178+
}
179+
180+
fun tryStartAbbrev(): Boolean {
181+
if (mComposing.isEmpty()) {
182+
changeState(SKKAbbrevState)
183+
return true
184+
}
185+
return false
186+
}
141187

142188
fun handleBackKey(): Boolean {
143189
if (!mRegistrationStack.isEmpty()) {
@@ -1151,36 +1197,13 @@ class SKKEngine(
11511197

11521198
internal fun changeInputMode(keyCode: Int): Boolean {
11531199
// 入力モード変更操作.変更したらtrue
1200+
// 他のケースは SKKService.onKeyDown に集約済み。
1201+
// 現在は Ctrl-Q (全角カナ/半角カナ切り替え) のみここで行う。
11541202
when (keyCode) {
1155-
'q'.code -> {
1156-
changeState(if (kanaState === SKKHiraganaState) SKKKatakanaState else SKKHiraganaState)
1157-
return true
1158-
}
1159-
11601203
17 /* Ctrl-Q */ -> {
11611204
changeState(SKKHanKanaState)
11621205
return true
11631206
}
1164-
1165-
'l'.code -> {
1166-
if (mComposing.length != 1 || mComposing[0] != 'z') {
1167-
if (state === SKKKanjiState) {
1168-
changeState(SKKAbbrevState)
1169-
} else {
1170-
changeState(SKKASCIIState, true)
1171-
}
1172-
return true
1173-
}
1174-
} // 「→」を入力するための例外
1175-
'L'.code -> {
1176-
changeState(SKKZenkakuState)
1177-
return true
1178-
}
1179-
1180-
'/'.code -> if (mComposing.isEmpty()) {
1181-
changeState(SKKAbbrevState)
1182-
return true
1183-
}
11841207
}
11851208

11861209
return false

app/src/main/java/jp/deadend/noname/skk/engine/SKKKanjiState.kt

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,6 @@ object SKKKanjiState : SKKState {
4040
}
4141

4242
when (codeLower) {
43-
'l'.code -> changeInputMode(keyCode)
44-
45-
'/'.code -> changeInputMode(keyCode)
46-
// abbrevはtransientなのでchangeInputModeで自動確定されない
47-
// ▽の状態で英数(abbrev)と仮名(kanji)を行き来するには kanaKey(-1010) と / を使うことにする
48-
// 一般的なキーコードが分かれば対応するが、emacsではabbrevから普通の▽(kanji)に行けないと思う
49-
50-
'q'.code -> {
51-
// カタカナ変換
52-
if (mKanjiKey.isNotEmpty()) {
53-
val str = if (kanaState == SKKHiraganaState) {
54-
hiragana2katakana(mKanjiKey.toString())
55-
} else {
56-
mKanjiKey.toString() // すでにひらがななのでそのまま
57-
}
58-
if (str != null) commitTextSKK(str)
59-
mKanjiKey.setLength(0)
60-
}
61-
changeState(kanaState)
62-
}
63-
6443
17 /* Ctrl-Q */ -> {
6544
if (mKanjiKey.isNotEmpty()) {
6645
val zenkakuKatakana = hiragana2katakana(mKanjiKey.toString())

app/src/main/res/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@
6767
<string name="pref_kana_key" translatable="false">PrefKeyKanaKey</string>
6868
<string name="pref_toggle_kana_key" translatable="false">PrefKeyToggleKanaKey</string>
6969
<string name="pref_cancel_key" translatable="false">PrefKeyCancelKey</string>
70+
<string name="pref_katakana_key" translatable="false">PrefKeyKatakanaKey</string>
71+
<string name="pref_ascii_key" translatable="false">PrefKeyASCIIKey</string>
72+
<string name="pref_zenkaku_key" translatable="false">PrefKeyZenkakuKey</string>
73+
<string name="pref_abbrev_key" translatable="false">PrefKeyAbbrevKey</string>
7074
<string name="pref_candidates_size" translatable="false">PrefKeyCandidatesSize</string>
7175
<string name="pref_candidates_reserve_lines" translatable="false">PrefKeyCandidatesReserveLines</string>
7276
<string name="pref_candidates_normal_lines" translatable="false">PrefKeyCandidatesNormalLines</string>

app/src/main/res/xml/prefs_hard_key.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@
2727
app:iconSpaceReserved="false"
2828
app:key="@string/pref_cancel_key"
2929
app:title="キャンセルキー" />
30+
<androidx.preference.Preference
31+
app:iconSpaceReserved="false"
32+
app:key="@string/pref_katakana_key"
33+
app:title="カタカナキー" />
34+
<androidx.preference.Preference
35+
app:iconSpaceReserved="false"
36+
app:key="@string/pref_ascii_key"
37+
app:title="直接入力キー" />
38+
<androidx.preference.Preference
39+
app:iconSpaceReserved="false"
40+
app:key="@string/pref_zenkaku_key"
41+
app:title="全角英数キー" />
42+
<androidx.preference.Preference
43+
app:iconSpaceReserved="false"
44+
app:key="@string/pref_abbrev_key"
45+
app:title="Abbrevキー" />
3046
<androidx.preference.CheckBoxPreference
3147
app:defaultValue="true"
3248
app:iconSpaceReserved="false"

app/src/test/java/jp/deadend/noname/skk/RomajiConverterTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,4 +314,5 @@ class RomajiConverterTest {
314314
tearDown()
315315
assertEquals(null, RomajiConverter.checkSpecialConsonants('q', 'q'.code))
316316
}
317-
}
317+
}
318+

0 commit comments

Comments
 (0)