/* Copyright 2019 niltea * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include QMK_KEYBOARD_H #ifdef OLED_DRIVER_ENABLE #include #include "lib/oled_helper.h" #endif /////////////////////////////////// // PAE ver 7.00 by OOOKA Toshihiko /////////////////////////////////// // Adobe PremiereとAfter Effectsをどちらも似た操作感で使う為の左手マクロパッド配列 //// このファイルの全体構成 // 変数の定義 // レイヤー名の定義 // マクロ名の定義 // コンボ名の定義、コンボ本体の定義 // キーマップ本体の定義 // エンコーダーの定義 // マクロ本体の定義 // 普通のマクロ、ダブルホールドマクロなどあります // 全体にサブルーチン化していない、都度継ぎ足したものなので、見にくくてすいません ///////// 色々変数定義 // フラグの定義 // Win/Mac, Premiere/After Effectsを都度切り替えて使います // Win or Mac 初期値はWin 1 static bool Win_or_Mac = true; //Premiere or AfterEffects 初期値はプレミア 1 static bool P_or_AE = true; // これを変えたければこのフラグ初期値と、このあとのenum layerIDで、デフォルトを何にしたいかで変えること // ツール切替トグル用のフラグ、初期値はVツール1 static bool V_toggle = true; // キーカウント用(レイヤーキーなのか単打なのか見分ける用) static int key_count = 0; // ダブルホールド用のフラグ 二つキーを押したらShift, Ctrl, Altになる機能 // Shiftを押しながらマウス、などに対応させるため。 // ダブルホールドがあるか、それぞれのキーが押されたかのフラグ、初期値は何もしていないので0 static bool Double_Hold = false; static bool CL_on = false; static bool CR_on = false; static bool SL_on = false; static bool SR_on = false; static bool AL_on = false; static bool AR_on = false; // タイマー(時間判定用) // 離したときにタッピングターム以内なら単打とみなす、それ以上時間がたっていたらおしまい // static uint32_t timer10 = 0; // static uint32_t timer11 = 0; ////////// LAYER //Premiereに3レイヤー、AEに3レイヤー、それぞれWinMacで計12レイヤー。あとテンキーとスペシャル(切り替え用)レイヤー enum layerID { // Win _0_Win_P = 0, // default layer Win/Premiere _1_Win_P, _2_Win_P, // 3レイヤーごとにペアになっているので、デフォにしたいものを3レイヤーごとここにもってくるとデフォを変えられるよ // 最後の切り替えマクロベースレイヤーをどれにしたかで処理を変えること _0_Win_AE, _1_Win_AE, _2_Win_AE, // Mac _0_Mac_P, _1_Mac_P, _2_Mac_P, _0_Mac_AE, _1_Mac_AE, _2_Mac_AE, // 切り替えレイヤーとテンキーレイヤー _SPECIAL, _ten, }; // keymap内にしこむマクロ enum custom_keycodes { // Win/Mac Premiere/AfrerEffects切り替えマクロ MC_Win_P = SAFE_RANGE, MC_Mac_P, MC_Win_AE, MC_Mac_AE, // ダブルホールドでモデファイア、その他で単打になるマクロ DHS_L, DHS_R, DHC_L, DHC_R, DHA_L, DHA_R, // Afterで5F単位で移動するマクロ MC_L5, MC_R5, // Premiereクリップのネスト(Winのみ対応) MC_CLIP_NEST, // 後方全選択ツールと前方全選択ツールを起動させて、選択ツールのトグルフラグをクリアする MC_SELECTALL_AFTER, MC_SELECTALL_BEFORE, // 単打でcvツール切り替え、押しっぱなしでレイヤー2になるもの MC_CV_L2, // 単打で何か、押しっぱなしでテンキー MC_TAP_LTten, }; // 同時押し定義部 // その1……アンドゥとBSの同時押しで英数発行 // その2……テンキーの同時押しで、透明度などによく使う数字を入れ込む // 100 enter, 50 enter, 0 enterを発生させる enum combo_events { EISU_Win, EISU_Mac, // WinとMacでアンドゥキーがC()G()で違うので2種定義 ZERO_ent, HALF_ent, FULL_ent, }; // 789 8+9...100ent // 456 5+6...50ent // 1230 2+3...0ent // 定義部 const uint16_t PROGMEM EISU_Win_combo[] = { C(KC_Z), KC_BSPC, COMBO_END}; const uint16_t PROGMEM EISU_Mac_combo[] = { G(KC_Z), KC_BSPC, COMBO_END}; const uint16_t PROGMEM ZERO_combo[] = { KC_2, KC_3, COMBO_END}; const uint16_t PROGMEM HALF_combo[] = { KC_5, KC_6, COMBO_END}; const uint16_t PROGMEM FULL_combo[] = { KC_8, KC_9, COMBO_END}; combo_t key_combos[COMBO_COUNT] = { [EISU_Win] = COMBO_ACTION(EISU_Win_combo), [EISU_Mac] = COMBO_ACTION(EISU_Mac_combo), [FULL_ent] = COMBO_ACTION(FULL_combo), [HALF_ent] = COMBO_ACTION(HALF_combo), [ZERO_ent] = COMBO_ACTION(ZERO_combo), }; // 同時押し本体 void process_combo_event(uint8_t combo_index, bool pressed) { switch(combo_index) { case EISU_Win: if (pressed) { SEND_STRING(SS_TAP(X_LANG2)); // 英数を発行(レイヤー名などを打ったあと大抵戻っていないので結構必要) } break; case EISU_Mac: if (pressed) { SEND_STRING(SS_TAP(X_LANG2)); // 同様 } break; case ZERO_ent: if (pressed) { SEND_STRING("0"SS_TAP(X_ENTER)); } break; case HALF_ent: if (pressed) { SEND_STRING("50"SS_TAP(X_ENTER)); } break; case FULL_ent: if (pressed) { SEND_STRING("100"SS_TAP(X_ENTER)); } break; } } // KEYMAP 本体////////////////////////////////////////////////////////////// // 一段目 1,2,3,4, 上のエンコのクリック, // 二段目 1,2,3,4, 下のエンコのクリック, // 親指 1,2,3, 4 // エンコーダーの回転はキーマップ以外で定義 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /////Premiere/////////////////// // Basic: 基本的な移動と再生と編集。エンコーダーはタイムラインの拡大と縮小、アンドゥリスト // In点へ /Alt | Out点へ /Alt | 前の編集点 /Ctl | 次の編集点 /Ctl || Undo (( Save )) Redo // Copy | Paste | 1F ← /Sft | 1F → /Sft || TL Zoom In(( TL全体 )) TL Zoom Out // | Undo | BS | 選択/カミソリ || 再生、停止 // // Edit: 編集 // In点設定 | Out点設定 |前の編集点までカット|次の編集点までカット|| ((このレイヤーでInOut)) // In点クリア | Out点クリア | 5F ← | 5F → || Vol - (( Mute )) Vol + // | Redo | 全レイヤーに編集点 | 編集点追加 || **ここを押しながら** // // Move: 再生や移動選択 // 前のマーカー | 次のマーカー | InOut再生 | 前後を再生 || ((アクティブウィンドウ最大化)) // マーカー消去 | マーク | 巻き戻し | 早送り || ((ネスト(Winのみ))) // | マッチフレーム | 前方全選択 |**ここを押しながら**|| 後方全選択 // // 注:LT(),MT()の中のキーは、Basic Keycodesでないといけない制約がある。なのでレイヤーキーの単キーは、単純なキーという縛りがあるよ。 // なので自由にしたいときはたいていコードを書いています。ソースが見にくくてすいません。 ///////////////////Windows // Win Premiere [_0_Win_P] = LAYOUT( DHA_L, DHA_R, DHC_L, DHC_R, C(KC_S), MC_TAP_LTten, C(KC_V), DHS_L, DHS_R, LT(_SPECIAL, KC_JYEN), C(KC_Z), KC_BSPC, MC_CV_L2, LT(_1_Win_P, KC_SPC) ), [_1_Win_P] = LAYOUT( KC_I, KC_O, KC_Q, KC_W, KC_SLSH, S(C(KC_I)), S(C(KC_O)), S(KC_LEFT), S(KC_RIGHT), KC_MUTE, S(C(KC_Z)), S(C(KC_K)), C(KC_K), _______ ), [_2_Win_P] = LAYOUT( S(C(KC_M)), S(KC_M), C(S(KC_SPC)), S(KC_K), KC_LBRC, C(S(A(KC_M))), KC_M, KC_J, KC_L, MC_CLIP_NEST, KC_F, MC_SELECTALL_BEFORE, _______, MC_SELECTALL_AFTER ), /////After Effects/////////////////// // Basic: Premiereと同様、基本的な移動と再生。同じ機能で使えるようにした。 // ワークIn点へ/Alt | ワークOut点へ/Alt| 前の編集点/Ctl | 次の編集点/Ctl || Undo (( Save )) Redo // Copy | Paste | 1F ← /Sft | 1F → /Sft || TL Zoom In(( TL全体 )) TL Zoom Out // | Undo | BS | 選択/てのひら || 再生、停止 // // Edit: レイヤーの編集 // ワークIn点設定 | ワークOut点設定 |Inからここまで消去 |ここからOutまで消去|| ((このレイヤーでInOut)) // Inをここへ移動 | Outをここへ移動 | 5F ← | 5F → || Vol - (( Mute )) Vol + // | Redo | Dupe | レイヤー分割 || **ここを押しながら** // // Tab: タブを開いたり閉じたり // R 回転タブ | S スケールタブ | P 位置タブ | T 透明度タブ || ((アクティブウィンドウ最大化)) // E エフェクトタブ | M マスクタブ | 前のキーF | 次のキーF || ((プリコンポ―ズ)) // | Uタブ全ひらき、とじ|スナップショット表示|**ここを押しながら**||スナップショット // // Win AfterEffects [_0_Win_AE] = LAYOUT( DHA_L, DHA_R, DHC_L, DHC_R, C(KC_S), MC_TAP_LTten, C(KC_V), DHS_L, DHS_R, LT(_SPECIAL, KC_SCLN), C(KC_Z), KC_BSPC, MC_CV_L2, LT(_1_Win_AE, KC_SPC) ), [_1_Win_AE] = LAYOUT( KC_B, KC_N, A(KC_RBRC), A(KC_BSLS), C(A(KC_B)), KC_RBRC, KC_BSLS, MC_L5, MC_R5, KC_MUTE, S(C(KC_Z)), C(KC_D), C(S(KC_D)), _______ ), [_2_Win_AE] = LAYOUT( KC_R, KC_S, KC_P, KC_T, KC_LBRC, KC_E, KC_M, KC_J, KC_K, C(S(KC_C)), KC_U, KC_F5, _______, S(KC_F5) ), /////////////////////Mac // Mac Premiere [_0_Mac_P] = LAYOUT( DHA_L, DHA_R, DHC_L, DHC_R, G(KC_S), MC_TAP_LTten, G(KC_V), DHS_L, DHS_R, LT(_SPECIAL, KC_JYEN), G(KC_Z), KC_BSPC, MC_CV_L2, LT(_1_Mac_P, KC_SPC) ), [_1_Mac_P] = LAYOUT( KC_I, KC_O, KC_Q, KC_W, KC_SLSH, S(G(KC_I)), S(G(KC_O)), S(KC_LEFT), S(KC_RIGHT), KC_MUTE, S(G(KC_Z)), S(G(KC_K)), G(KC_K), _______ ), [_2_Mac_P] = LAYOUT( S(G(KC_M)), S(KC_M), A(KC_K), S(KC_K), KC_LBRC, G(S(A(KC_M))), KC_M, KC_J, KC_L, _______, KC_F, MC_SELECTALL_BEFORE, _______, MC_SELECTALL_AFTER ), // Macにはネスト化がないです。Winは強引にAlt、C、Nと強引にコマンドをおしているため // InOut再生だけWinとMacでショートカットが違う Win C(S(KC_SPC)) Mac A(KC_K) // Mac AfterEffects [_0_Mac_AE] = LAYOUT( DHA_L, DHA_R, DHC_L, DHC_R, G(KC_S), MC_TAP_LTten, G(KC_V), DHS_L, DHS_R, LT(_SPECIAL, KC_SCLN), G(KC_Z), KC_BSPC, MC_CV_L2, LT(_1_Mac_AE, KC_SPC) ), [_1_Mac_AE] = LAYOUT( KC_B, KC_N, A(KC_RBRC), A(KC_BSLS), G(A(KC_B)), KC_RBRC, KC_BSLS, MC_L5, MC_R5, KC_MUTE, S(G(KC_Z)), G(KC_D), G(S(KC_D)), _______ ), [_2_Mac_AE] = LAYOUT( KC_R, KC_S, KC_P, KC_T, KC_LBRC, KC_E, KC_M, KC_J, KC_K, G(S(KC_C)), KC_U, KC_F5, _______, S(KC_F5) ), /////// Win/Mac Premiere/After Effects切り替え [_SPECIAL] = LAYOUT( XXXXXXX, XXXXXXX, MC_Mac_AE, MC_Mac_P, XXXXXXX, MC_Mac_AE, MC_Mac_P, MC_Win_AE, MC_Win_P, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX ), // テンキー [_ten] = LAYOUT( KC_ENTER, KC_7, KC_8, KC_9, KC_DOT, _______, KC_4, KC_5, KC_6, KC_MINUS, KC_1, KC_2, KC_3, KC_0 ), }; ////////////////////// // エンコーダ― Mac/Win, Premiere/AfterEffectsでキーバインド切り替える // 上のエンコーダー // 右に回したとき // フラグで場合わけ // 左に回したとき // フラグで場合わけ // 下のエンコーダー、以下同様 // フラグで場合わけして、エンコーダーで場合わけして、左右で場合分けしたほうが分かりやすかったかも void encoder_update_user(uint8_t index, bool clockwise) { if (index == 0) { // 上のエンコーダ―(P/AEで、Undo/Redo共通) // 右に回したとき if (clockwise) { if (layer_state_is(_ten)) { // テンキーのときには上 SEND_STRING(SS_TAP(X_UP)); } else { // それ以外はRedo if (Win_or_Mac) { // win SEND_STRING(SS_LSFT(SS_LCTL(SS_TAP(X_Z)))); } else { // mac SEND_STRING(SS_LSFT(SS_LGUI(SS_TAP(X_Z)))); } } } else { // 左に回したとき if (layer_state_is(_ten)) { // テンキーのときには下 SEND_STRING(SS_TAP(X_DOWN)); } else { // それ以外はUndo if (Win_or_Mac) { // win SEND_STRING(SS_LCTL(SS_TAP(X_Z))); } else { // mac SEND_STRING(SS_LGUI(SS_TAP(X_Z))); } } } } else if (index == 1) { ////////// //下のエンコーダー // 右に回したとき if (clockwise) { if (layer_state_is(_ten)) { // テンキーのときにはシフト上 SEND_STRING(SS_LSFT(SS_TAP(X_UP))); // レイヤーなどで場合分け } else if (layer_state_is(_1_Win_P) ==1 || layer_state_is(_1_Win_AE) ==1 || layer_state_is(_1_Mac_P) ==1 || layer_state_is(_1_Mac_AE) ==1) { // Layer 1 ON (Win/Mac, P/AE)で Vol+ SEND_STRING(SS_TAP(X_VOLU)); } else { // タイムラインの拡大縮小PremiereとAfterでバインドがちがう!!! if (P_or_AE) { ///// Premiere 日本語の:キーをUSで打っているので。 SEND_STRING("'"); } else { ////// AfterEffects 日本語の^キーをUSで打っているので。 SEND_STRING("="); } } // 左に回したとき } else { if (layer_state_is(_ten)) { // テンキーのときにはシフト下 SEND_STRING(SS_LSFT(SS_TAP(X_DOWN))); // レイヤーなどで場合分け } else if (layer_state_is(_1_Win_P) ==1 || layer_state_is(_1_Win_AE) ==1 || layer_state_is(_1_Mac_P) ==1 || layer_state_is(_1_Mac_AE) ==1) { // Layer 1 ON (Win/Mac, P/AE)で Vol- SEND_STRING(SS_TAP(X_VOLD)); } else { // タイムラインの拡大縮小(Win/Mac) ///// Premiere, After ともに-バインド SEND_STRING("-"); } } } } // Macros /////////////////////////////////////////// bool process_record_user(uint16_t keycode, keyrecord_t *record) { // 何かを押されるごとにキーカウンターを1増やす(リセットされるのはCVキーを押したときのみ) if (record->event.pressed) { key_count = key_count + 1; } switch (keycode) { ///////////////////////////////////////////////// // Win/Mac, Premiere/AfterEffectsのレイヤーの切り替え ///////////////////////////////////////////////// case MC_Win_P: if (record->event.pressed) { layer_clear(); //Windows/Premiereはベースレイヤーなのでクリアするだけでよい // もしベースレイヤーを変更したら以下を生かしてね // layer_on(_0_Win_P); Win_or_Mac = true; P_or_AE = true; } break; case MC_Win_AE: if (record->event.pressed) { layer_clear(); layer_on(_0_Win_AE); Win_or_Mac = true; P_or_AE = false; } break; case MC_Mac_P: if (record->event.pressed) { layer_clear(); layer_on(_0_Mac_P); Win_or_Mac = false; P_or_AE = true; } break; case MC_Mac_AE: if (record->event.pressed) { layer_clear(); layer_on(_0_Mac_AE); Win_or_Mac = false; P_or_AE = false; } break; ///////////////////////////////////////////////// ///////////////////////////////////////////////// // Afterで5F戻るマクロ case MC_L5: if (record->event.pressed) { SEND_STRING(SS_TAP(X_PGUP)); SEND_STRING(SS_TAP(X_PGUP)); SEND_STRING(SS_TAP(X_PGUP)); SEND_STRING(SS_TAP(X_PGUP)); SEND_STRING(SS_TAP(X_PGUP)); } break; // Afterで5F戻るマクロ case MC_R5: if (record->event.pressed) { SEND_STRING(SS_TAP(X_PGDOWN)); SEND_STRING(SS_TAP(X_PGDOWN)); SEND_STRING(SS_TAP(X_PGDOWN)); SEND_STRING(SS_TAP(X_PGDOWN)); SEND_STRING(SS_TAP(X_PGDOWN)); } break; ///// クリップのネスト case MC_CLIP_NEST: if (record->event.pressed) { // クリップのネスト化、強引にAlt, C, Nとコマンドを押しているだけなので、Macではできない // 間に空ループ入れて早すぎないように。 SEND_STRING(SS_TAP(X_LALT)); while (timer_elapsed(record->event.time) <= 100) {} SEND_STRING(SS_TAP(X_C)); while (timer_elapsed(record->event.time) <= 100) {} SEND_STRING(SS_TAP(X_N)); } break; // 後方選択、前方選択ツールを使ったあと、次に必ず選択ツールになるようにフラグを立てるマクロ case MC_SELECTALL_AFTER: if (record->event.pressed) { SEND_STRING(SS_TAP(X_A)); V_toggle = false; } break; case MC_SELECTALL_BEFORE: if (record->event.pressed) { SEND_STRING(SS_LSFT(SS_TAP(X_A))); V_toggle = false; } break; ////////////////////////////////////// ////////////////////////////////////// ////////////////////////////////////// // 単打で何か、押しっぱなしでレイヤーキーになる // C/Vの切り替え /レイヤー2 case MC_CV_L2: if (record->event.pressed) { key_count = 0; // とりあえずレイヤー2をオンにする if (Win_or_Mac) { if (P_or_AE) { layer_on(_2_Win_P); } else { layer_on(_2_Win_AE); } } else { if (P_or_AE) { layer_on(_2_Mac_P); } else { layer_on(_2_Mac_AE); } } } else { // レイヤー2をオフ if (Win_or_Mac) { if (P_or_AE) { layer_off(_2_Win_P); } else { layer_off(_2_Win_AE); } } else { if (P_or_AE) { layer_off(_2_Mac_P); } else { layer_off(_2_Mac_AE); } } // 離された時点で他のキーを押していないなら単打と判断 if (key_count == 0) { if (P_or_AE) { //V(選択)とC(カミソリ)をトグル Permiere if (V_toggle) { SEND_STRING(SS_TAP(X_C)); V_toggle = false; } else { SEND_STRING(SS_TAP(X_V)); V_toggle = true; } } else { //V(選択)とH(手のひら)をトグル After if (V_toggle) { SEND_STRING(SS_TAP(X_H)); V_toggle = false; } else { SEND_STRING(SS_TAP(X_V)); V_toggle = true; } } } } break; // Copy /テンキーレイヤー case MC_TAP_LTten: if (record->event.pressed) { key_count = 0; layer_on(_ten); // 押されたらとりあえずテンキーをオンにしておく } else { layer_off(_ten); // 離された時点で他のキーを押していないなら単打と判断 if (key_count == 0) { // Copy if (Win_or_Mac) { SEND_STRING(SS_LCTL(SS_TAP(X_C))); } else { SEND_STRING(SS_LGUI(SS_TAP(X_C))); } } } break; ///////////////////////////////////////////////// // ダブルホールドキー 単打でいろいろ、両方押したらモデファイアになるもの ///////////////////////////////////////////////// ////////////////// case DHS_L: if (record->event.pressed) { // 押したとき SL_on = true; ///// R側も押されていたらShift発行 if (SR_on) { SEND_STRING(SS_DOWN(X_LSHIFT)); Double_Hold = true; } } else { // 離したとき SL_on = false; if (CR_on) { // もう一方がまだ押されているなら何もしない } else { // もう一方は今オフ、ダブルホールドがあったか単押しかで場合分け if (Double_Hold) { SEND_STRING(SS_UP(X_LSHIFT)); Double_Hold = false; } else { // 単押し、単離し // 前1F移動 if (P_or_AE) { SEND_STRING(SS_TAP(X_LEFT)); } else { SEND_STRING(SS_TAP(X_PGUP)); } } } } break; case DHS_R: if (record->event.pressed) { // 押したとき SR_on = true; ///// L側も押されていたらShift発行 if (SL_on) { SEND_STRING(SS_DOWN(X_LSHIFT)); Double_Hold = true; } } else { // 離したとき SR_on = false; if (SL_on) { // もう一方がまだ押されているなら何もしない } else { // もう一方は今オフ、ダブルホールドがあったか単押しかで場合分け if (Double_Hold) { SEND_STRING(SS_UP(X_LSHIFT)); Double_Hold = false; } else { // 単押し、単離し // あと1F移動 if (P_or_AE) { SEND_STRING(SS_TAP(X_RIGHT)); } else { SEND_STRING(SS_TAP(X_PGDOWN)); } } } } break; ////////////////// case DHC_L: if (record->event.pressed) { // 押したとき CL_on = true; ///// R側も押されていたらCtrl発行 if (CR_on) { SEND_STRING(SS_DOWN(X_LCTRL)); Double_Hold = true; } } else { // 離したとき CL_on = false; if (CR_on) { // もう一方がまだ押されているなら何もしない } else { // もう一方は今オフ、ダブルホールドがあったか単押しかで場合分け if (Double_Hold) { SEND_STRING(SS_UP(X_LCTRL)); Double_Hold = false; } else { // 単押し、単離し // 前の編集点へ P KC_UP / AE C(S(A(KC_LEFT))) if (P_or_AE) { SEND_STRING(SS_TAP(X_UP)); } else { if (Win_or_Mac) { SEND_STRING(SS_LCTL(SS_LSFT(SS_LALT(SS_TAP(X_LEFT))))); } else { SEND_STRING(SS_LGUI(SS_LSFT(SS_LALT(SS_TAP(X_LEFT))))); } } } } } break; case DHC_R: if (record->event.pressed) { // 押したとき CR_on = true; ///// L側も押されていたらCTRL発行 if (CL_on) { SEND_STRING(SS_DOWN(X_LCTRL)); Double_Hold = true; } } else { // 離したとき CR_on = false; if (CL_on) { // もう一方がまだ押されているなら何もしない } else { // もう一方は今オフ、ダブルホールドがあったか単押しかで場合分け if (Double_Hold) { SEND_STRING(SS_UP(X_LCTRL)); Double_Hold = false; } else { // 単押し、単離し // 次の編集点へ P KC_DOWN / AE C(S(A(KC_RIGHT))) if (P_or_AE) { SEND_STRING(SS_TAP(X_DOWN)); } else { if (Win_or_Mac) { SEND_STRING(SS_LCTL(SS_LSFT(SS_LALT(SS_TAP(X_RIGHT))))); } else { SEND_STRING(SS_LGUI(SS_LSFT(SS_LALT(SS_TAP(X_RIGHT))))); } } } } } break; /////////////////// case DHA_L: if (record->event.pressed) { // 押したとき AL_on = true; ///// R側も押されていたらAlt発行 if (AR_on) { SEND_STRING(SS_DOWN(X_LALT)); Double_Hold = true; } } else { // 離したとき AL_on = false; if (AR_on) { // もう一方がまだ押されているなら何もしない } else { // もう一方は今オフ、ダブルホールドがあったか単押しかで場合分け if (Double_Hold) { SEND_STRING(SS_UP(X_LALT)); SEND_STRING(SS_TAP(X_LALT)); // ただupすると単押しALTが発動するのでタップしてオフっておく Double_Hold = false; } else { // 単押し、単離し // 現在のアクティブレイヤーによって処理を場合わけ // In点へ移動(P)、ワークエリアIn点へ移動(AE) if (P_or_AE) { SEND_STRING(SS_LSFT(SS_TAP(X_I))); } else { SEND_STRING(SS_LSFT(SS_TAP(X_HOME))); } } } } break; case DHA_R: if (record->event.pressed) { // 押したとき AR_on = true; ///// R側も押されていたらAlt発行 if (AL_on) { SEND_STRING(SS_DOWN(X_LALT)); Double_Hold = true; } } else { // 離したとき AR_on = false; if (AL_on) { // もう一方がまだ押されているなら何もしない } else { // もう一方は今オフ、ダブルホールドがあったか単押しかで場合分け if (Double_Hold) { SEND_STRING(SS_UP(X_LALT)); SEND_STRING(SS_TAP(X_LALT)); // ただupすると単押しALTが発動するのでタップしてオフっておく Double_Hold = false; } else { // 単押し、単離し // 現在のアクティブレイヤーによって処理を場合わけ // Out点へ移動(P)、ワークエリアOut点へ移動(AE) if (P_or_AE) { SEND_STRING(SS_LSFT(SS_TAP(X_O))); } else { SEND_STRING(SS_LSFT(SS_TAP(X_END))); } } } } break; } return true; };