--- nono/wx/wxsoftkey.cpp 2026/04/29 17:05:04 1.1.1.9 +++ nono/wx/wxsoftkey.cpp 2026/04/29 17:05:07 1.1.1.10 @@ -45,10 +45,14 @@ WXSoftKeyPanel::WXSoftKeyPanel(wxWindow DoSize(); + // トグル動作にするキー + toggle.emplace(KC_SHIFT, 0); + toggle.emplace(KC_SHIFT_L, 0); + toggle.emplace(KC_SHIFT_R, 0); + toggle.emplace(KC_CTRL, 0); + // 残光の初期化。 // persistence は keydata 分の配列ではなく共通キーコード分の配列。 - // 使われない領域も多いが、共通キーコードから keydata 番号への逆引きは - // 面倒なので。 persistence.resize(KC_max); std::fill(persistence.begin(), persistence.end(), 0); @@ -68,8 +72,14 @@ WXSoftKeyPanel::WXSoftKeyPanel(wxWindow // デストラクタ WXSoftKeyPanel::~WXSoftKeyPanel() { - // SHIFT キーのワンショットは解放する? + // ウィンドウクローズでトグルキーのワンショットは開放する // (長押しは開放しない) + for (const auto& k : toggle) { + auto code = k.second; + if (code) { + KeyUp(code); + } + } timer.Stop(); @@ -208,6 +218,16 @@ WXSoftKeyPanel::OnKeyChanged(wxCommandEv persistence[keycode] = 9; } + // トグルキーが開放されていたらトグル情報をクリアする。 + // ハードウェアキーボードを含む VM 側で開放された場合と、 + // ソフトウェアキーボードの KeyUp() で開放された場合のどちらも + // ここでクリア。 + for (auto& k : toggle) { + if (gKeyboard->IsPressed(k.first) == false) { + k.second = 0; + } + } + Refresh(); } @@ -293,20 +313,14 @@ WXSoftKeyPanel::Draw(wxDC& dc) } else { timer.Stop(); } - -#if 0 - // X68k キーボードだとどこに表示するか - SetTextBackColor(color.Background); - wxString utfstr(wxT("右クリックで長押し")); - const char *sjis = (const char *)utfstr.mb_str(conv); - DrawStringSJIS(dc, 190 * unit, 2 * unit, sjis, TA::Disable); -#endif } // 指定のキーを一つ (枠から刻印まで) 描画する。 void WXSoftKeyPanel::DrawKey(wxDC& dc, const keydata_t& key) { + uint attr = TA::Normal; + // 枠 wxPoint pt(key.x * unit, key.y * unit); wxSize sz(key.w * unit + 1, key.h * unit + 1); @@ -318,6 +332,14 @@ WXSoftKeyPanel::DrawKey(wxDC& dc, const disp = key.disp[0]; } + // トグルキーのワンショット押しは太字で表示を区別したい + const auto it = toggle.find(key.keycode); + if (it != toggle.end()) { + if (it->second) { + attr = TA::Em; + } + } + // Shift_JIS に変換 wxString utfstr(disp, wxConvUTF8); const char *sjis = (const char *)utfstr.mb_str(conv); @@ -361,7 +383,7 @@ WXSoftKeyPanel::DrawKey(wxDC& dc, const } else { if (lf == NULL) { // 1行の場合 - DrawStringSJIS(dc, pt.x, pt.y, sjis); + DrawStringSJIS(dc, pt.x, pt.y, sjis, attr); } else { // 2行の場合 DrawStringSJIS(dc, pt.x, pt.y, sjis1); @@ -432,20 +454,6 @@ WXSoftKeyPanel::FindKeydata(uint keycode assertmsg(0, "keycode %d not found", keycode); } -// keycode が SHIFT キーなら true を返す -// (SHIFT キーが押されているかとかではない) -/*static*/ bool -WXSoftKeyPanel::IsShiftKey(uint keycode) -{ - if (keycode == KC_SHIFT_L || - keycode == KC_SHIFT_R || - keycode == KC_SHIFT) - { - return true; - } - return false; -} - // マウス左クリック (Down) イベント void WXSoftKeyPanel::OnLeftDown(wxMouseEvent& event) @@ -454,40 +462,30 @@ WXSoftKeyPanel::OnLeftDown(wxMouseEvent& const keydata_t *key = GetKeydataFromPoint(pt); if (key != NULL) { - DoLeftDown(key); + DoLeftDown(key->keycode); } } // マウス左クリック (Down) 処理 void -WXSoftKeyPanel::DoLeftDown(const keydata_t *key) +WXSoftKeyPanel::DoLeftDown(uint code) { - assert(key); - - // SHIFT キーの左クリックはトグル状動作。 - // SHIFT 状態で押すと、すべての SHIFT キーを開放。 - // 非 SHIFT 状態で押すと、次のキー押下までこの SHIFT キーを押下維持。 - if (IsShiftKey(key->keycode)) { - if (gKeyboard->IsShift()) { - // SHIFT 状態で SHIFT キーが押されたのですべての SHIFT キーを開放 - if (key->keycode == KC_SHIFT) { - KeyUp(*key); - } else { - KeyUp(FindKeydata(KC_SHIFT_L)); - KeyUp(FindKeydata(KC_SHIFT_R)); - } + auto it = toggle.find(code); + if (it != toggle.end()) { + // トグルキーはここで完結。LeftUp では何もしない。 + // second のクリアは KeyUp() からコールバックされる OnKeyChanged() + // で行っている。 + if (gKeyboard->IsPressed(code)) { + KeyUp(code); } else { - // 非 SHIFT 状態で SHIFT キーが押されたのでこのキーを押下 - KeyDown(*key); - shift_hold = false; + KeyDown(code); + it->second = code; } - - // SHIFT キーなら LeftUp では何もしない - leftdown_key = NULL; + leftdown_key = KC_none; } else { - // SHIFT 以外のキーは押下して LeftUp のために覚えておく - KeyDown(*key); - leftdown_key = key; + // トグルでない通常キーはここで押下して LeftUp のために覚えておく + KeyDown(code); + leftdown_key = code; } } @@ -497,27 +495,21 @@ WXSoftKeyPanel::OnLeftUp(wxMouseEvent& e { // Up 時は、これが起きた地点のキーコードではなく // 直近に LeftDown したキーコードをターゲットにする。 - const keydata_t *key = leftdown_key; + uint code = leftdown_key; - if (key != NULL) { - KeyUp(*key); + if (code != KC_none) { + KeyUp(code); - // キーが離された時、長押しでない SHIFT キーがあれば開放 - if (gKeyboard->IsShift() && shift_hold == false) { - // XXX どの SHIFT が存在するのか分からないのがなんかアレ - if (gKeyboard->IsPressed(KC_SHIFT_L)) { - KeyUp(FindKeydata(KC_SHIFT_L)); - } - if (gKeyboard->IsPressed(KC_SHIFT_R)) { - KeyUp(FindKeydata(KC_SHIFT_R)); - } - if (gKeyboard->IsPressed(KC_SHIFT)) { - KeyUp(FindKeydata(KC_SHIFT)); + // 通常キーが離されたら、トグルキーはすべて開放 + for (const auto& k : toggle) { + auto tcode = k.second; + if (tcode) { + KeyUp(tcode); } } } - leftdown_key = NULL; + leftdown_key = KC_none; } // マウス左ダブルクリックイベント @@ -537,7 +529,7 @@ WXSoftKeyPanel::OnLeftDClick(wxMouseEven const keydata_t *key = GetKeydataFromPoint(pt); if (key != NULL) { - DoLeftDown(key); + DoLeftDown(key->keycode); } } @@ -554,14 +546,10 @@ WXSoftKeyPanel::OnRightDown(wxMouseEvent uint code = key->keycode; if (gKeyboard->IsPressed(code)) { // 押されていたら開放 - KeyUp(*key); + KeyUp(code); } else { // 押されてなければ長押し開始 - KeyDown(*key); - - if (IsShiftKey(key->keycode)) { - shift_hold = true; - } + KeyDown(code); } } } @@ -595,20 +583,16 @@ WXSoftKeyPanel::GetKeydataFromPoint(cons // このキーが押された処理 void -WXSoftKeyPanel::KeyDown(const keydata_t& key) +WXSoftKeyPanel::KeyDown(uint code) { - uint code = key.keycode; - // VM に通知 (Keyboard がホストに通知する) gKeyboard->MakeKey(code); } // このキーが放された処理 void -WXSoftKeyPanel::KeyUp(const keydata_t& key) +WXSoftKeyPanel::KeyUp(uint code) { - uint code = key.keycode; - // VM に通知 (Keyboard がホストに通知する) gKeyboard->BreakKey(code); }