aboutsummaryrefslogtreecommitdiff
path: root/docs/ja
diff options
context:
space:
mode:
authorshela <shelaf@users.noreply.github.com>2020-07-31 14:31:34 +0900
committerGitHub <noreply@github.com>2020-07-30 22:31:34 -0700
commit3c7fc3c82ee943638fc978a03f038249d33c25cf (patch)
treec80447440d52ee271e1c12f07bebc4ee014305a7 /docs/ja
parent2ec2f80bfce352e60d58dd5248ab347f7272c5b3 (diff)
downloadqmk_firmware-3c7fc3c82ee943638fc978a03f038249d33c25cf.tar.gz
qmk_firmware-3c7fc3c82ee943638fc978a03f038249d33c25cf.zip
[Docs] Update Japanese translation of feature_tap_dance.md. (#9808)
* Update Japanese translation of feature_tap_dance.md. * fix original document version. * Update docs/ja/feature_tap_dance.md
Diffstat (limited to 'docs/ja')
-rw-r--r--docs/ja/feature_tap_dance.md512
1 files changed, 245 insertions, 267 deletions
diff --git a/docs/ja/feature_tap_dance.md b/docs/ja/feature_tap_dance.md
index 5425b2a42..01d060757 100644
--- a/docs/ja/feature_tap_dance.md
+++ b/docs/ja/feature_tap_dance.md
@@ -1,39 +1,28 @@
1# タップダンス: 1つのキーが3つ、5つまたは100の異なる動作をします 1# タップダンス: 1つのキーが3つ、5つまたは100の異なる動作をします
2 2
3<!--- 3<!---
4 original document: 0.9.0:docs/feature_tap_dance.md 4 original document: 0.9.44:docs/feature_tap_dance.md
5 git diff 0.9.0 HEAD -- docs/feature_tap_dance.md | cat 5 git diff 0.9.44 HEAD -- docs/feature_tap_dance.md | cat
6--> 6-->
7 7
8## イントロダクション 8## イントロダクション :id=introduction
9 9
10セミコロンキーを1回叩くと、セミコロンが送信されます。2回素早く叩くと、コロンが送信されます。3回叩くと、あなたのキーボードのLEDが激しく踊るように明滅します。これは、タップダンスでできることの一例です。それは、コミュニティが提案したとても素敵なファームウェアの機能の1つで、[algernon](https://github.com/algernon) がプルリクエスト [#451](https://github.com/qmk/qmk_firmware/pull/451) で考えて作ったものです。algernon が述べる機能は次の通りです: 10セミコロンキーを1回叩くと、セミコロンが送信されます。2回素早く叩くと、コロンが送信されます。3回叩くと、あなたのキーボードのLEDが激しく踊るように明滅します。これは、タップダンスでできることの一例です。それは、コミュニティが提案したとても素敵なファームウェアの機能の1つで、[algernon](https://github.com/algernon) がプルリクエスト [#451](https://github.com/qmk/qmk_firmware/pull/451) で考えて作ったものです。algernon が述べる機能は次の通りです:
11 11
12この機能を使うと、特定のキーが、タップした回数に基づいて異なる振る舞いをします。そして、割り込みがあった時は、割り込み前に上手く処理されます。 12この機能を使うと、特定のキーが、タップした回数に基づいて異なる振る舞いをします。そして、割り込みがあった時は、割り込み前に上手く処理されます。
13 13
14## `ACTION_FUNCTION_TAP` との比較について 14## タップダンスの使い方 :id=how-to-use
15 15最初に、あなたの `rules.mk` ファイルで `TAP_DANCE_ENABLE = yes` と設定する必要があります。なぜならば、デフォルトでは無効になっているからです。これでファームウェアのサイズが1キロバイトほど増加します。
16`ACTION_FUNCTION_TAP` はタップダンスに似た機能を提供しますが、注目すべきいくつかの重要な違いがあります。違いを確認するため、いくつかの設定を調べてみましょう。1つのキーを1回タップすると `Space` キーが送信され、2回タップすると `Enter` キーが送信されるよう設定します。
17
18`ACTION_FUNCTION_TAP` では、これを設定するのはかなり大変で、キーの順番が割り込まれた時に割り込んだキーが最初に送られるという問題に直面します。例えば、`SPC a` は、もし `SPC` と `a` が `TAPPING_TERM` で設定した時間内に両方とも入力された場合、結果として `a SPC` が送信されます。タップダンス機能を使う場合、正しく `SPC a` が送信されます(`TAPPING_TERM` で設定した時間内に `SPC` と `a` を入力した場合であっても)。
19
20割り込みを正しくハンドリングして目的を達成するため、タップダンスの実装ではシステムの2つの部分をフックします: `process_record_quantum()` とマトリックススキャンです。この2つの部分については以下で説明しますが、今注意すべき点は、マトリックススキャンでは、キーが押されていない時でもタップのシーケンスをタイムアウトにできる必要があるということです。そうすれば、`TAPPING_TERM` の時間が経過した後、`SPC` だけがタイムアウトになって登録されます。
21
22## タップダンスの使い方
23
24一般論は十分です。タップダンスの実際の使い方を見てみましょう!
25
26最初に、あなたの `rules.mk` ファイルで `TAP_DANCE_ENABLE=yes` と設定する必要があります。なぜならば、デフォルトでは無効になっているからです。これでファームウェアのサイズが1キロバイトほど増加します。
27 16
28オプションで、あなたの `config.h` ファイルに次のような設定を追加して、`TAPPING_TERM` の時間をカスタマイズしたほうが良いです。 17オプションで、あなたの `config.h` ファイルに次のような設定を追加して、`TAPPING_TERM` の時間をカスタマイズしたほうが良いです。
29 18
30``` 19```c
31#define TAPPING_TERM 175 20#define TAPPING_TERM 175
32``` 21```
33 22
34`TAPPING_TERM` の時間は、あなたのタップダンスのキーのタップとタップの間の時間として許可された最大の時間で、ミリ秒単位で計測されます。例えば、もし、あなたがこの上にある `#define` ステートメントを使い、1回タップすると `Space` が送信され、2回タップすると `Enter` が送信されるタップダンスキーをセットアップした場合、175ミリ秒以内に2回キーをタップすれば `ENT` だけが送信されるでしょう。もし、1回タップしてから175ミリ秒以上待ってからもう一度タップすると、`SPC SPC` が送信されます。 23`TAPPING_TERM` の時間は、あなたのタップダンスのキーのタップとタップの間の時間として許可された最大の時間で、ミリ秒単位で計測されます。例えば、もし、あなたがこの上にある `#define` ステートメントを使い、1回タップすると `Space` が送信され、2回タップすると `Enter` が送信されるタップダンスキーをセットアップした場合、175ミリ秒以内に2回キーをタップすれば `ENT` だけが送信されるでしょう。もし、1回タップしてから175ミリ秒以上待ってからもう一度タップすると、`SPC SPC` が送信されます。
35 24
36次に、いくつかのタップダンスのキーを定義するためには、`TD()` マクロ — `F()` マクロに似ています — を使うのが最も簡単です。これは数字を受け取り、この数字は後で `tap_dance-actions` 配列のインデックスとして使われます。 25次に、いくつかのタップダンスのキーを定義するためには、`TD()` マクロを使うのが最も簡単です。これは数字を受け取り、この数字は後で `tap_dance-actions` 配列のインデックスとして使われます。
37 26
38その後、`tap_dance_actions` 配列を使って、タップダンスキーを押した時のアクションを定義します。現在は、5つの可能なオプションがあります: 27その後、`tap_dance_actions` 配列を使って、タップダンスキーを押した時のアクションを定義します。現在は、5つの可能なオプションがあります:
39 28
@@ -56,7 +45,7 @@
56最後に、5番目のオプションは、もし、タップダンスキーをコードに追加した後、非タップダンスキーが奇妙な振る舞いを始めた時に特に役に立ちます。ありうる問題は、あなたがタップダンスキーを使いやすくするために `TAPPING_TERM` の時間を変更した結果、その他のキーが割り込みを処理する方法が変わってしまったというものです。 45最後に、5番目のオプションは、もし、タップダンスキーをコードに追加した後、非タップダンスキーが奇妙な振る舞いを始めた時に特に役に立ちます。ありうる問題は、あなたがタップダンスキーを使いやすくするために `TAPPING_TERM` の時間を変更した結果、その他のキーが割り込みを処理する方法が変わってしまったというものです。
57 46
58 47
59## 実装の詳細 48## 実装の詳細 :id=implementation
60 49
61さて、説明の大部分はここまでです! 以下に挙げているいくつかの例に取り組むことができるようになり、あなた自身のタップダンスの機能を開発できるようになります。しかし、もし、あなたが裏側で起きていることをより深く理解したいのであれば、続けてそれが全てどのように機能するかの説明を読みましょう! 50さて、説明の大部分はここまでです! 以下に挙げているいくつかの例に取り組むことができるようになり、あなた自身のタップダンスの機能を開発できるようになります。しかし、もし、あなたが裏側で起きていることをより深く理解したいのであれば、続けてそれが全てどのように機能するかの説明を読みましょう!
62 51
@@ -72,9 +61,9 @@
72 61
73柔軟性のために、タップダンスは、キーコードの組み合わせにも、ユーザー関数にもなることができます。後者は、より高度なタップ回数の制御や、LED を点滅させたり、バックライトをいじったり、等々の制御を可能にします。これは、1つの共用体と、いくつかの賢いマクロによって成し遂げられています。 62柔軟性のために、タップダンスは、キーコードの組み合わせにも、ユーザー関数にもなることができます。後者は、より高度なタップ回数の制御や、LED を点滅させたり、バックライトをいじったり、等々の制御を可能にします。これは、1つの共用体と、いくつかの賢いマクロによって成し遂げられています。
74 63
75# 実装例 64## 実装例 :id=examples
76 65
77## シンプルな実装例 66### シンプルな実装例 :id=simple-example
78 67
79ここに1つの定義のための簡単な例があります。 68ここに1つの定義のための簡単な例があります。
80 69
@@ -85,21 +74,24 @@
85```c 74```c
86// タップダンスの宣言 75// タップダンスの宣言
87enum { 76enum {
88 TD_ESC_CAPS = 0 77 TD_ESC_CAPS,
89}; 78};
90 79
91// タップダンスの定義 80// タップダンスの定義
92qk_tap_dance_action_t tap_dance_actions[] = { 81qk_tap_dance_action_t tap_dance_actions[] = {
93 // 1回タップすると Escape キー、2回タップすると Caps Lock。 82 // 1回タップすると Escape キー、2回タップすると Caps Lock。
94 [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS) 83 [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
95// ほかの宣言もカンマで区切ってここに記述します
96}; 84};
97 85
98// レイヤー定義で、キーコードの代わりにタップダンスキーを追加します 86// キーコードの代わりにタップダンスキーを追加します
99TD(TD_ESC_CAPS) 87const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
88 // ...
89 TD(TD_ESC_CAPS)
90 // ...
91};
100``` 92```
101 93
102## 複雑な実装例 94### 複雑な実装例 :id=complex-examples
103 95
104このセクションでは、いくつかの複雑なタップダンスの例を詳しく説明します。 96このセクションでは、いくつかの複雑なタップダンスの例を詳しく説明します。
105例で使われている全ての列挙型はこのように宣言します。 97例で使われている全ての列挙型はこのように宣言します。
@@ -107,107 +99,104 @@ TD(TD_ESC_CAPS)
107```c 99```c
108// 全ての例のための列挙型定義 100// 全ての例のための列挙型定義
109enum { 101enum {
110 CT_SE = 0, 102 CT_SE,
111 CT_CLN, 103 CT_CLN,
112 CT_EGG, 104 CT_EGG,
113 CT_FLSH, 105 CT_FLSH,
114 X_TAP_DANCE 106 X_TAP_DANCE
115}; 107};
116``` 108```
117### 例1: 1回タップすると `:` を送信し、2回タップすると `;` を送信する 109#### 例1: 1回タップすると `:` を送信し、2回タップすると `;` を送信する :id=example-1
118 110
119```c 111```c
120void dance_cln_finished (qk_tap_dance_state_t *state, void *user_data) { 112void dance_cln_finished(qk_tap_dance_state_t *state, void *user_data) {
121 if (state->count == 1) { 113 if (state->count == 1) {
122 register_code (KC_RSFT); 114 register_code16(KC_COLN);
123 register_code (KC_SCLN); 115 } else {
124 } else { 116 register_code(KC_SCLN);
125 register_code (KC_SCLN); 117 }
126 }
127} 118}
128 119
129void dance_cln_reset (qk_tap_dance_state_t *state, void *user_data) { 120void dance_cln_reset(qk_tap_dance_state_t *state, void *user_data) {
130 if (state->count == 1) { 121 if (state->count == 1) {
131 unregister_code (KC_RSFT); 122 unregister_code16(KC_COLN);
132 unregister_code (KC_SCLN); 123 } else {
133 } else { 124 unregister_code(KC_SCLN);
134 unregister_code (KC_SCLN); 125 }
135 }
136} 126}
137 127
138// 全てのタップダンス関数はここに定義します。ここでは1つだけ示します。 128// 全てのタップダンス関数はここに定義します。ここでは1つだけ示します。
139qk_tap_dance_action_t tap_dance_actions[] = { 129qk_tap_dance_action_t tap_dance_actions[] = {
140 [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset) 130 [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset),
141}; 131};
142``` 132```
143 133
144### 例2: 100回タップした後に "Safety Dance!" を送信します 134#### 例2: 100回タップした後に "Safety Dance!" を送信します :id=example-2
145 135
146```c 136```c
147void dance_egg (qk_tap_dance_state_t *state, void *user_data) { 137void dance_egg(qk_tap_dance_state_t *state, void *user_data) {
148 if (state->count >= 100) { 138 if (state->count >= 100) {
149 SEND_STRING ("Safety dance!"); 139 SEND_STRING("Safety dance!");
150 reset_tap_dance (state); 140 reset_tap_dance(state);
151 } 141 }
152} 142}
153 143
154qk_tap_dance_action_t tap_dance_actions[] = { 144qk_tap_dance_action_t tap_dance_actions[] = {
155 [CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg) 145 [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
156}; 146};
157``` 147```
158 148
159### 例3: 1つずつ LED を点灯させてから消灯する 149#### 例3: 1つずつ LED を点灯させてから消灯する :id=example-3
160 150
161```c 151```c
162// タップする毎に、LED を右から左に点灯します。 152// タップする毎に、LED を右から左に点灯します。
163// 4回目のタップで、右から左に消灯します。 153// 4回目のタップで、右から左に消灯します。
164void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) { 154void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) {
165 switch (state->count) { 155 switch (state->count) {
166 case 1: 156 case 1:
167 ergodox_right_led_3_on(); 157 ergodox_right_led_3_on();
168 break; 158 break;
169 case 2: 159 case 2:
170 ergodox_right_led_2_on(); 160 ergodox_right_led_2_on();
171 break; 161 break;
172 case 3: 162 case 3:
173 ergodox_right_led_1_on(); 163 ergodox_right_led_1_on();
174 break; 164 break;
175 case 4: 165 case 4:
176 ergodox_right_led_3_off(); 166 ergodox_right_led_3_off();
177 _delay_ms(50); 167 wait_ms(50);
178 ergodox_right_led_2_off(); 168 ergodox_right_led_2_off();
179 _delay_ms(50); 169 wait_ms(50);
180 ergodox_right_led_1_off(); 170 ergodox_right_led_1_off();
181 } 171 }
182} 172}
183 173
184// 4回目のタップで、キーボードをフラッシュ状態にセットします。 174// 4回目のタップで、キーボードをフラッシュ状態にセットします。
185void dance_flsh_finished(qk_tap_dance_state_t *state, void *user_data) { 175void dance_flsh_finished(qk_tap_dance_state_t *state, void *user_data) {
186 if (state->count >= 4) { 176 if (state->count >= 4) {
187 reset_keyboard(); 177 reset_keyboard();
188 reset_tap_dance(state); 178 }
189 }
190} 179}
191 180
192// もしフラッシュ状態にならない場合、LED を左から右に消灯します。 181// もしフラッシュ状態にならない場合、LED を左から右に消灯します。
193void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) { 182void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) {
194 ergodox_right_led_1_off(); 183 ergodox_right_led_1_off();
195 _delay_ms(50); 184 wait_ms(50);
196 ergodox_right_led_2_off(); 185 ergodox_right_led_2_off();
197 _delay_ms(50); 186 wait_ms(50);
198 ergodox_right_led_3_off(); 187 ergodox_right_led_3_off();
199} 188}
200 189
201// 全てのタップダンス関数を一緒に表示しています。この例3は "CT_FLASH" です。 190// 全てのタップダンス関数を一緒に表示しています。この例3は "CT_FLASH" です。
202qk_tap_dance_action_t tap_dance_actions[] = { 191qk_tap_dance_action_t tap_dance_actions[] = {
203 [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT) 192 [CT_SE] = ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT),
204 ,[CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset) 193 [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset),
205 ,[CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg) 194 [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
206 ,[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED (dance_flsh_each, dance_flsh_finished, dance_flsh_reset) 195 [CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset)
207}; 196};
208``` 197```
209 198
210### 例4: クアッドファンクションのタップダンス 199#### 例4: クアッドファンクションのタップダンス :id=example-4
211 200
212[DanielGGordon](https://github.com/danielggordon) によるもの 201[DanielGGordon](https://github.com/danielggordon) によるもの
213 202
@@ -219,40 +208,37 @@ qk_tap_dance_action_t tap_dance_actions[] = {
219* 2回タップ = `Escape` を送信 208* 2回タップ = `Escape` を送信
220* 2回タップして押し続ける = `Alt` を送信 209* 2回タップして押し続ける = `Alt` を送信
221 210
222## 準備
223
224'クアッドファンクションのタップダンス' を利用できるようにするには、いくつかのものが必要になります。 211'クアッドファンクションのタップダンス' を利用できるようにするには、いくつかのものが必要になります。
225 212
226`keymap.c` ファイルの先頭、つまりキーマップの前に、以下のコードを追加します。 213`keymap.c` ファイルの先頭、つまりキーマップの前に、以下のコードを追加します。
227 214
228```c 215```c
229typedef struct { 216typedef struct {
230 bool is_press_action; 217 bool is_press_action;
231 int state; 218 uint8_t state;
232} tap; 219} tap;
233 220
234enum { 221enum {
235 SINGLE_TAP = 1, 222 SINGLE_TAP = 1,
236 SINGLE_HOLD = 2, 223 SINGLE_HOLD,
237 DOUBLE_TAP = 3, 224 DOUBLE_TAP,
238 DOUBLE_HOLD = 4, 225 DOUBLE_HOLD,
239 DOUBLE_SINGLE_TAP = 5, //シングルタップを2回送信 226 DOUBLE_SINGLE_TAP, // シングルタップを2回送信
240 TRIPLE_TAP = 6, 227 TRIPLE_TAP,
241 TRIPLE_HOLD = 7 228 TRIPLE_HOLD
242}; 229};
243 230
244// タップダンスの列挙型 231// タップダンスの列挙型
245enum { 232enum {
246 X_CTL = 0, 233 X_CTL,
247 SOME_OTHER_DANCE 234 SOME_OTHER_DANCE
248}; 235};
249 236
250int cur_dance (qk_tap_dance_state_t *state); 237uint8_t cur_dance(qk_tap_dance_state_t *state);
251
252//xタップダンスのための関数。キーマップで利用できるようにするため、ここに置きます。
253void x_finished (qk_tap_dance_state_t *state, void *user_data);
254void x_reset (qk_tap_dance_state_t *state, void *user_data);
255 238
239// xタップダンスのための関数。キーマップで利用できるようにするため、ここに置きます。
240void x_finished(qk_tap_dance_state_t *state, void *user_data);
241void x_reset(qk_tap_dance_state_t *state, void *user_data);
256``` 242```
257 243
258次に、`keymap.c` ファイルの末尾に、次のコードを追加する必要があります。 244次に、`keymap.c` ファイルの末尾に、次のコードを追加する必要があります。
@@ -288,68 +274,64 @@ void x_reset (qk_tap_dance_state_t *state, void *user_data);
288 * 3つ目の点については、'DOUBLE_SINGLE_TAP' が存在しますが、これは完全にはテストされていません 274 * 3つ目の点については、'DOUBLE_SINGLE_TAP' が存在しますが、これは完全にはテストされていません
289 * 275 *
290 */ 276 */
291int cur_dance (qk_tap_dance_state_t *state) { 277uint8_t cur_dance(qk_tap_dance_state_t *state) {
292 if (state->count == 1) { 278 if (state->count == 1) {
293 if (state->interrupted || !state->pressed) return SINGLE_TAP; 279 if (state->interrupted || !state->pressed) return SINGLE_TAP;
294 //キーは割り込まれていませんが、まだ押し続けられています。'HOLD' を送信することを意味します。 280 // キーは割り込まれていませんが、まだ押し続けられています。'HOLD' を送信することを意味します。
295 else return SINGLE_HOLD; 281 else return SINGLE_HOLD;
296 } 282 } else if (state->count == 2) {
297 else if (state->count == 2) { 283 // DOUBLE_SINGLE_TAP は "pepper" と入力することと、'pp' と入力したときに実際に
298 /* 284 // ダブルタップしたい場合とを区別するためのものです。
299 * DOUBLE_SINGLE_TAP は "pepper" と入力することと、'pp' と入力したときに実際に 285 // この戻り値の推奨されるユースケースは、'ダブルタップ' 動作やマクロではなく、
300 * ダブルタップしたい場合とを区別するためのものです。 286 // そのキーの2つのキー入力を送信したい場合です。
301 * この戻り値の推奨されるユースケースは、'ダブルタップ' 動作やマクロではなく、 287 if (state->interrupted) return DOUBLE_SINGLE_TAP;
302 * そのキーの2つのキー入力を送信したい場合です。 288 else if (state->pressed) return DOUBLE_HOLD;
303 */ 289 else return DOUBLE_TAP;
304 if (state->interrupted) return DOUBLE_SINGLE_TAP; 290 }
305 else if (state->pressed) return DOUBLE_HOLD; 291
306 else return DOUBLE_TAP; 292 // 誰も同じ文字を3回入力しようとしていないと仮定します(少なくとも高速には)。
307 } 293 // タップダンスキーが 'KC_W' で、"www." と高速に入力したい場合、ここに例外を追加して
308 //誰も同じ文字を3回入力しようとしていないと仮定します(少なくとも高速には)。 294 // 'TRIPLE_SINGLE_TAP' を返し、'DOUBLE_SINGLE_TAP' のようにその列挙型を定義する必要があります。
309 //タップダンスキーが 'KC_W' で、"www." と高速に入力したい場合、ここに例外を追加して 295 if (state->count == 3) {
310 //'TRIPLE_SINGLE_TAP' を返し、'DOUBLE_SINGLE_TAP' のようにその列挙型を定義する 296 if (state->interrupted || !state->pressed) return TRIPLE_TAP;
311 //必要があります。 297 else return TRIPLE_HOLD;
312 if (state->count == 3) { 298 } else return 8; // マジックナンバー。いつかこのメソッドはより多くの押下に対して機能するよう拡張されるでしょう
313 if (state->interrupted || !state->pressed) return TRIPLE_TAP;
314 else return TRIPLE_HOLD;
315 }
316 else return 8; //マジックナンバー。いつかこのメソッドはより多くの押下に対して機能するよう拡張されるでしょう
317} 299}
318 300
319//'x' タップダンスの 'tap' のインスタンスをンスタンス化ます 301//'x' タップダンスの 'tap' のインスタンスを生成します
320static tap xtap_state = { 302static tap xtap_state = {
321 .is_press_action = true, 303 .is_press_action = true,
322 .state = 0 304 .state = 0
323}; 305};
324 306
325void x_finished (qk_tap_dance_state_t *state, void *user_data) { 307void x_finished(qk_tap_dance_state_t *state, void *user_data) {
326 xtap_state.state = cur_dance(state); 308 xtap_state.state = cur_dance(state);
327 switch (xtap_state.state) { 309 switch (xtap_state.state) {
328 case SINGLE_TAP: register_code(KC_X); break; 310 case SINGLE_TAP: register_code(KC_X); break;
329 case SINGLE_HOLD: register_code(KC_LCTRL); break; 311 case SINGLE_HOLD: register_code(KC_LCTRL); break;
330 case DOUBLE_TAP: register_code(KC_ESC); break; 312 case DOUBLE_TAP: register_code(KC_ESC); break;
331 case DOUBLE_HOLD: register_code(KC_LALT); break; 313 case DOUBLE_HOLD: register_code(KC_LALT); break;
332 case DOUBLE_SINGLE_TAP: register_code(KC_X); unregister_code(KC_X); register_code(KC_X); 314 // 最後の case は高速入力用です。キーが `f` であると仮定します:
333 //最後の case は高速入力用です。キーが `f` であると仮定します: 315 // 例えば、`buffer` という単語を入力するとき、`Esc` ではなく `ff` を送信するようにします。
334 //例えば、`buffer` という単語を入力するとき、`Esc` ではなく `ff` を送信するようにします。 316 // 高速入力時に `ff` と入力するには、次の文字は `TAPPING_TERM` 以内に入力する必要があります。
335 //高速入力時に `ff` と入力するには、次の文字は `TAPPING_TERM` 以内に入力する必要があります。 317 // `TAPPING_TERM` はデフォルトでは 200ms です。
336 //`TAPPING_TERM` はデフォルトでは 200ms です。 318 case DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X);
337 } 319 }
338} 320}
339 321
340void x_reset (qk_tap_dance_state_t *state, void *user_data) { 322void x_reset(qk_tap_dance_state_t *state, void *user_data) {
341 switch (xtap_state.state) { 323 switch (xtap_state.state) {
342 case SINGLE_TAP: unregister_code(KC_X); break; 324 case SINGLE_TAP: unregister_code(KC_X); break;
343 case SINGLE_HOLD: unregister_code(KC_LCTRL); break; 325 case SINGLE_HOLD: unregister_code(KC_LCTRL); break;
344 case DOUBLE_TAP: unregister_code(KC_ESC); break; 326 case DOUBLE_TAP: unregister_code(KC_ESC); break;
345 case DOUBLE_HOLD: unregister_code(KC_LALT); 327 case DOUBLE_HOLD: unregister_code(KC_LALT);
346 case DOUBLE_SINGLE_TAP: unregister_code(KC_X); 328 case DOUBLE_SINGLE_TAP: unregister_code(KC_X);
347 } 329 }
348 xtap_state.state = 0; 330 xtap_state.state = 0;
349} 331}
350 332
351qk_tap_dance_action_t tap_dance_actions[] = { 333qk_tap_dance_action_t tap_dance_actions[] = {
352 [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,x_finished, x_reset) 334 [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset)
353}; 335};
354``` 336```
355 337
@@ -359,90 +341,91 @@ qk_tap_dance_action_t tap_dance_actions[] = {
359 341
360> この設定の "hold" は、タップダンスのタイムアウト(`ACTION_TAP_DANCE_FN_ADVANCED_TIME` 参照)の **後** に起こります。即座に "hold" を得るためには、条件から `state->interrupted` の確認を除きます。結果として、複数回のタップのための時間をより多く持つことで快適な長いタップの期限を使うことができ、そして、"hold" のために長く待たないようにすることができます(2倍の `TAPPING TERM` で開始してみてください)。 342> この設定の "hold" は、タップダンスのタイムアウト(`ACTION_TAP_DANCE_FN_ADVANCED_TIME` 参照)の **後** に起こります。即座に "hold" を得るためには、条件から `state->interrupted` の確認を除きます。結果として、複数回のタップのための時間をより多く持つことで快適な長いタップの期限を使うことができ、そして、"hold" のために長く待たないようにすることができます(2倍の `TAPPING TERM` で開始してみてください)。
361 343
362### 例5: タップダンスを高度なモッドタップとレイヤータップキーに使う :id=example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys 344#### 例5: タップダンスを高度なモッドタップとレイヤータップキーに使う :id=example-5
363 345
364タップダンスは、タップされたコードが基本的なキーコード以外の場合に、 `MT()` と `LT()` マクロをエミュレートするのに利用できます。これは、通常 `Shift` を必要とする '(' や '{' のようなキーや、`Control + X` のように他の修飾されたキーコードをタップされたキーコードとして送信することに役立ちます。 346タップダンスは、タップされたコードが基本的なキーコード以外の場合に、 `MT()` と `LT()` マクロをエミュレートするのに利用できます。これは、通常 `Shift` を必要とする '(' や '{' のようなキーや、`Control + X` のように他の修飾されたキーコードをタップされたキーコードとして送信することに役立ちます。
365 347
366あなたのレイヤーとカスタムキーコードの下に、以下のコードを追加します。 348あなたのレイヤーとカスタムキーコードの下に、以下のコードを追加します。
367 349
368```c 350```c
369//タップダンスのキーコード 351// タップダンスのキーコード
370enum td_keycodes { 352enum td_keycodes {
371 ALT_LP //例: 押していると `LALT`、タップすると `(`。それぞれのタップダンスの追加のキーコードを追加します 353 ALT_LP // 例: 押していると `LALT`、タップすると `(`。それぞれのタップダンスの追加のキーコードを追加します
372}; 354};
373 355
374//必要な数のタップダンス状態を含むタイプを定義します 356// 必要な数のタップダンス状態を含むタイプを定義します
375typedef enum { 357typedef enum {
376 SINGLE_TAP, 358 SINGLE_TAP,
377 SINGLE_HOLD, 359 SINGLE_HOLD,
378 DOUBLE_SINGLE_TAP 360 DOUBLE_SINGLE_TAP
379} td_state_t; 361} td_state_t;
380 362
381//タップダンスの状態の型のグローバルインスタンスを作ります 363// タップダンスの状態の型のグローバルインスタンスを作ります
382static td_state_t td_state; 364static td_state_t td_state;
383 365
384//タップダンス関数を宣言します: 366// タップダンス関数を宣言します:
385 367
386//現在のタップダンスの状態を特定するための関数 368// 現在のタップダンスの状態を特定するための関数
387int cur_dance (qk_tap_dance_state_t *state); 369uint8_t cur_dance(qk_tap_dance_state_t *state);
388 370
389//それぞれのタップダンスキーコードに適用する `finished` と `reset` 関数 371// それぞれのタップダンスキーコードに適用する `finished` と `reset` 関数
390void altlp_finished (qk_tap_dance_state_t *state, void *user_data); 372void altlp_finished(qk_tap_dance_state_t *state, void *user_data);
391void altlp_reset (qk_tap_dance_state_t *state, void *user_data); 373void altlp_reset(qk_tap_dance_state_t *state, void *user_data);
392``` 374```
393 375
394キーレイアウト(`LAYOUT`)の下に、タップダンスの関数を定義します。 376キーレイアウト(`LAYOUT`)の下に、タップダンスの関数を定義します。
395 377
396```c 378```c
397// 返却するタップダンス状態を特定します 379// 返却するタップダンス状態を特定します
398int cur_dance (qk_tap_dance_state_t *state) { 380uint8_t cur_dance(qk_tap_dance_state_t *state) {
399 if (state->count == 1) { 381 if (state->count == 1) {
400 if (state->interrupted || !state->pressed) { return SINGLE_TAP; } 382 if (state->interrupted || !state->pressed) return SINGLE_TAP;
401 else { return SINGLE_HOLD; } 383 else return SINGLE_HOLD;
402 } 384 }
403 if (state->count == 2) { return DOUBLE_SINGLE_TAP; } 385
404 else { return 3; } // 上記で返却する最大の状態の値より大きい任意の数 386 if (state->count == 2) return DOUBLE_SINGLE_TAP;
387 else return 3; // 上記で返却する最大の状態の値より大きい任意の数
405} 388}
406 389
407// 定義する各タップダンスキーコードのとりうる状態を制御します: 390// 定義する各タップダンスキーコードのとりうる状態を制御します:
408 391
409void altlp_finished (qk_tap_dance_state_t *state, void *user_data) { 392void altlp_finished(qk_tap_dance_state_t *state, void *user_data) {
410 td_state = cur_dance(state); 393 td_state = cur_dance(state);
411 switch (td_state) { 394 switch (td_state) {
412 case SINGLE_TAP: 395 case SINGLE_TAP:
413 register_code16(KC_LPRN); 396 register_code16(KC_LPRN);
414 break; 397 break;
415 case SINGLE_HOLD: 398 case SINGLE_HOLD:
416 register_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_on(_MY_LAYER)` を使います 399 register_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_on(_MY_LAYER)` を使います
417 break; 400 break;
418 case DOUBLE_SINGLE_TAP: // タップ時間内に2つの括弧 `((` の入れ子を可能にします 401 case DOUBLE_SINGLE_TAP: // タップ時間内に2つの括弧 `((` の入れ子を可能にします
419 tap_code16(KC_LPRN); 402 tap_code16(KC_LPRN);
420 register_code16(KC_LPRN); 403 register_code16(KC_LPRN);
421 } 404 }
422} 405}
423 406
424void altlp_reset (qk_tap_dance_state_t *state, void *user_data) { 407void altlp_reset(qk_tap_dance_state_t *state, void *user_data) {
425 switch (td_state) { 408 switch (td_state) {
426 case SINGLE_TAP: 409 case SINGLE_TAP:
427 unregister_code16(KC_LPRN); 410 unregister_code16(KC_LPRN);
428 break; 411 break;
429 case SINGLE_HOLD: 412 case SINGLE_HOLD:
430 unregister_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_off(_MY_LAYER)` を使います 413 unregister_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_off(_MY_LAYER)` を使います
431 break; 414 break;
432 case DOUBLE_SINGLE_TAP: 415 case DOUBLE_SINGLE_TAP:
433 unregister_code16(KC_LPRN); 416 unregister_code16(KC_LPRN);
434 } 417 }
435} 418}
436 419
437// 各タップダンスキーコードの `ACTION_TAP_DANCE_FN_ADVANCED()` を定義し、`finished` と `reset` 関数を渡します 420// 各タップダンスキーコードの `ACTION_TAP_DANCE_FN_ADVANCED()` を定義し、`finished` と `reset` 関数を渡します
438qk_tap_dance_action_t tap_dance_actions[] = { 421qk_tap_dance_action_t tap_dance_actions[] = {
439 [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset) 422 [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset)
440}; 423};
441``` 424```
442 425
443それぞれのタップダンスキーコードをキーマップに含めるときは、`TD()` マクロでキーコードをラップします。例: `TD(ALT_LP)` 426それぞれのタップダンスキーコードをキーマップに含めるときは、`TD()` マクロでキーコードをラップします。例: `TD(ALT_LP)`
444 427
445### 例6: タップダンスを一時的なレイヤー切り替えとレイヤートグルキーに使う 428#### 例6: タップダンスを一時的なレイヤー切り替えとレイヤートグルキーに使う :id=example-6
446 429
447タップダンスは、MO(layer) と TG(layer) 機能を模倣することにも使用できます。この例では、1回タップすると `KC_QUOT` 、1回押してそのまま押し続けたら `MO(_MY_LAYER)` 、2回タップしたときは `TG(_MY_LAYER)` として機能するキーを設定します。 430タップダンスは、MO(layer) と TG(layer) 機能を模倣することにも使用できます。この例では、1回タップすると `KC_QUOT` 、1回押してそのまま押し続けたら `MO(_MY_LAYER)` 、2回タップしたときは `TG(_MY_LAYER)` として機能するキーを設定します。
448 431
@@ -450,98 +433,93 @@ qk_tap_dance_action_t tap_dance_actions[] = {
450 433
451```c 434```c
452typedef struct { 435typedef struct {
453 bool is_press_action; 436 bool is_press_action;
454 int state; 437 uint8_t state;
455} tap; 438} tap;
456 439
457//必要な数のタップダンス状態のタイプを定義します 440// 必要な数のタップダンス状態のタイプを定義します
458enum { 441enum {
459 SINGLE_TAP = 1, 442 SINGLE_TAP = 1,
460 SINGLE_HOLD = 2, 443 SINGLE_HOLD,
461 DOUBLE_TAP = 3 444 DOUBLE_TAP
462}; 445};
463 446
464enum { 447enum {
465 QUOT_LAYR = 0 //カスタムタップダンスキー。他のタップダンスキーはこの列挙型に追加します 448 QUOT_LAYR, // カスタムタップダンスキー。他のタップダンスキーはこの列挙型に追加します
466}; 449};
467 450
468//タップダンスキーで使われる関数を宣言します 451// タップダンスキーで使われる関数を宣言します
469 452
470//全てのタップダンスに関連する関数 453// 全てのタップダンスに関連する関数
471int cur_dance (qk_tap_dance_state_t *state); 454uint8_t cur_dance(qk_tap_dance_state_t *state);
472 455
473//個別のタップダンスに関連する関数 456// 個別のタップダンスに関連する関数
474void ql_finished (qk_tap_dance_state_t *state, void *user_data); 457void ql_finished(qk_tap_dance_state_t *state, void *user_data);
475void ql_reset (qk_tap_dance_state_t *state, void *user_data); 458void ql_reset(qk_tap_dance_state_t *state, void *user_data);
476``` 459```
477 460
478あなたの `keymap.c` ファイルの最後の方に以下のコードを追加します。 461あなたの `keymap.c` ファイルの最後の方に以下のコードを追加します。
479 462
480```c 463```c
481//現在のタップダンスの状態を決定します 464// 現在のタップダンスの状態を決定します
482int cur_dance (qk_tap_dance_state_t *state) { 465uint8_t cur_dance(qk_tap_dance_state_t *state) {
483 if (state->count == 1) { 466 if (state->count == 1) {
484 if (!state->pressed) { 467 if (!state->pressed) return SINGLE_TAP;
485 return SINGLE_TAP; 468 else return SINGLE_HOLD;
486 } else { 469 } else if (state->count == 2) return DOUBLE_TAP;
487 return SINGLE_HOLD; 470 else return 8;
488 }
489 } else if (state->count == 2) {
490 return DOUBLE_TAP;
491 }
492 else return 8;
493} 471}
494 472
495//この例のタップダンスキーに関連付けられた "tap" 構造体を初期化します 473// この例のタップダンスキーに関連付けられた "tap" 構造体を初期化します
496static tap ql_tap_state = { 474static tap ql_tap_state = {
497 .is_press_action = true, 475 .is_press_action = true,
498 .state = 0 476 .state = 0
499}; 477};
500 478
501//タップダンスキーの動作をコントロールする関数 479// タップダンスキーの動作をコントロールする関数
502void ql_finished (qk_tap_dance_state_t *state, void *user_data) { 480void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
503 ql_tap_state.state = cur_dance(state); 481 ql_tap_state.state = cur_dance(state);
504 switch (ql_tap_state.state) { 482 switch (ql_tap_state.state) {
505 case SINGLE_TAP: 483 case SINGLE_TAP:
506 tap_code(KC_QUOT); 484 tap_code(KC_QUOT);
507 break; 485 break;
508 case SINGLE_HOLD: 486 case SINGLE_HOLD:
509 layer_on(_MY_LAYER); 487 layer_on(_MY_LAYER);
510 break; 488 break;
511 case DOUBLE_TAP: 489 case DOUBLE_TAP:
512 //レイヤーが既にセットされているか確認します 490 // レイヤーが既にセットされているか確認します
513 if (layer_state_is(_MY_LAYER)) { 491 if (layer_state_is(_MY_LAYER)) {
514 //レイヤーが既にセットされていたら、オフにします。 492 // レイヤーが既にセットされていたら、オフにします。
515 layer_off(_MY_LAYER); 493 layer_off(_MY_LAYER);
516 } else { 494 } else {
517 //レイヤーがセットされていなかったら、オンにします。 495 // レイヤーがセットされていなかったら、オンにします。
518 layer_on(_MY_LAYER); 496 layer_on(_MY_LAYER);
519 } 497 }
520 break; 498 break;
521 } 499 }
522} 500}
523 501
524void ql_reset (qk_tap_dance_state_t *state, void *user_data) { 502void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
525 //キーを押し続けていて今離したら、レイヤーをオフに切り替えます。 503 // キーを押し続けていて今離したら、レイヤーをオフに切り替えます。
526 if (ql_tap_state.state==SINGLE_HOLD) { 504 if (ql_tap_state.state == SINGLE_HOLD) {
527 layer_off(_MY_LAYER); 505 layer_off(_MY_LAYER);
528 } 506 }
529 ql_tap_state.state = 0; 507 ql_tap_state.state = 0;
530} 508}
531 509
532//タップダンスキーを機能に関連付けます 510// タップダンスキーを機能に関連付けます
533qk_tap_dance_action_t tap_dance_actions[] = { 511qk_tap_dance_action_t tap_dance_actions[] = {
534 [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275) 512 [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275)
535}; 513};
536``` 514```
537 515
538上記のコードは、前の例で使われたコードに似ています。注意する1つのポイントは、必要に応じてレイヤーを切り替えられるように、どのレイヤーがアクティブになっているかいつでも確認できる必要があることです。これを実現するために、引数で与えられた `layer` がアクティブなら `true` を返す `layer_state_is( layer )` を使います。 516上記のコードは、前の例で使われたコードに似ています。注意する1つのポイントは、必要に応じてレイヤーを切り替えられるように、どのレイヤーがアクティブになっているかいつでも確認できる必要があることです。これを実現するために、引数で与えられた `layer` がアクティブなら `true` を返す `layer_state_is(layer)` を使います。
539 517
540`cur_dance()` と `ql_tap_state` の使い方は、上の例と似ています。 518`cur_dance()` と `ql_tap_state` の使い方は、上の例と似ています。
541 519
542`ql_finished` 関数における `case:SINGLE_TAP` は、上の例と似ています。`case:SINGLE_HOLD` は、`ql_reset()` と連動してタップダンスキーを押している間 `_MY_LAYER` に切り替わり、キーを離した時に `_MY_LAYER` から離れます。これは、`MO(_MY_LAYER)` に似ています。`case:DOUBLE_TAP` は、`_MY_LAYER` がアクティブレイヤーかどうかを確認することによって動きます。そして、その結果に基づいてレイヤーのオン・オフをトグルします。これは `TG(_MY_LAYER)` に似ています。 520`ql_finished` 関数における `case:SINGLE_TAP` は、上の例と似ています。`SINGLE_HOLD` の case では、`ql_reset()` と連動してタップダンスキーを押している間 `_MY_LAYER` に切り替わり、キーを離した時に `_MY_LAYER` から離れます。これは、`MO(_MY_LAYER)` に似ています。`DOUBLE_TAP` の case では、`_MY_LAYER` がアクティブレイヤーかどうかを確認することによって動きます。そして、その結果に基づいてレイヤーのオン・オフをトグルします。これは `TG(_MY_LAYER)` に似ています。
543 521
544`tap_dance_actions[]` は、上の例に似ています。 `ACTION_TAP_DANCE_FN_ADVANCED()` の代わりに `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` を使ったことに注意してください。 522`tap_dance_actions[]` は、上の例に似ています。 `ACTION_TAP_DANCE_FN_ADVANCED()` の代わりに `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` を使ったことに注意してください。
545この理由は、私は、非タップダンスキーを使うにあたり `TAPPING_TERM` が短い(175ミリ秒以内)方が好きなのですが、タップダンスのアクションを確実に完了させるには短すぎるとわかったからです——そのため、ここでは時間を275ミリ秒に増やしています。 523この理由は、私は、非タップダンスキーを使うにあたり `TAPPING_TERM` が短い(175ミリ秒以内)方が好きなのですが、タップダンスのアクションを確実に完了させるには短すぎるとわかったからです——そのため、ここでは時間を275ミリ秒に増やしています。
546 524
547最後に、このタップダンスキーを動かすため、忘れずに `TD(QUOT_LAYR)` を `keymaps[]` に加えてください。 525最後に、このタップダンスキーを動かすため、忘れずに `TD(QUOT_LAYR)` を `keymaps[]` に加えてください。