--- nono/wx/wxsoftkey.cpp 2026/04/29 17:04:28 1.1 +++ nono/wx/wxsoftkey.cpp 2026/04/29 17:04:53 1.1.1.6 @@ -1,57 +1,79 @@ // // nono -// Copyright (C) 2019 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "wxheader.h" -#include "wxcolor.h" #include "wxsoftkey.h" +#include "wxcolor.h" +#include "wxmainview.h" #include "wxtextscreen.h" +#include "sram.h" // -// LUNA ソフトウェアキーボード (パネル) +// ソフトウェアキーボード (パネル) 共通部分 // +// エンター記号。 +// 描画の際にキー刻印文字列の半角文字数から描画幅を決定しており、 +// エンター記号は半角2文字幅で描いているので実際の文字列も2文字にしておく。 +// そうすると "\\n" が意味的にもちょうどいい。 +// これは幅を算出するのに使うだけで表示はされない。 +#define EnterMark "\\n" + // イベントテーブル -wxBEGIN_EVENT_TABLE(WXLunaSoftKeyPanel, inherited) - EVT_LEFT_DOWN(WXLunaSoftKeyPanel::OnLeftDown) - EVT_LEFT_UP(WXLunaSoftKeyPanel::OnLeftUp) - EVT_LEFT_DCLICK(WXLunaSoftKeyPanel::OnLeftDClick) - EVT_RIGHT_DOWN(WXLunaSoftKeyPanel::OnRightDown) - EVT_PAINT(WXLunaSoftKeyPanel::OnPaint) - EVT_SIZE(WXLunaSoftKeyPanel::OnSize) +wxBEGIN_EVENT_TABLE(WXSoftKeyPanel, inherited) + EVT_LEFT_DOWN(WXSoftKeyPanel::OnLeftDown) + EVT_LEFT_UP(WXSoftKeyPanel::OnLeftUp) + EVT_LEFT_DCLICK(WXSoftKeyPanel::OnLeftDClick) + EVT_RIGHT_DOWN(WXSoftKeyPanel::OnRightDown) + EVT_PAINT(WXSoftKeyPanel::OnPaint) + EVT_SIZE(WXSoftKeyPanel::OnSize) + EVT_TIMER(wxID_ANY, WXSoftKeyPanel::OnTimer) wxEND_EVENT_TABLE() // コンストラクタ -WXLunaSoftKeyPanel::WXLunaSoftKeyPanel(wxWindow *parent) +WXSoftKeyPanel::WXSoftKeyPanel(wxWindow *parent, + const std::vector& keydata_, int u_width_, int u_height_) : inherited(parent) + , keydata(keydata_) { - // LUNA では - // BS キーの左隣 (0x5c) は円記号ではなくバックスラッシュ。 - // それを SHIFT したやつ(0x7c) は破線でないパイプ。 - // そのもう一つ左隣 (0x7e) はオーバーラインではなくチルダ。 - SetGlyph5C(true); - SetGlyph7E(true); + u_width = u_width_; + u_height = u_height_; - DoSize(); + // 比較用のバッファ (初回更新させるため true で埋めておく) + const std::vector& pressed = gKeyboard->GetPressed(); + last_pressed.resize(pressed.size()); + std::fill(last_pressed.begin(), last_pressed.end(), true); + last_modifier = (Modifier)-1; + + // このパネルへのキー入力はメインビューへのキー入力と同じ。 + Connect(wxEVT_KEY_UP, wxKeyEventHandler(WXMainView::OnKeyUp), NULL, + gMainView); + Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(WXMainView::OnKeyDown), NULL, + gMainView); + + // 更新間隔は適当 + timer.SetOwner(this); + timer.Start(100); } // デストラクタ -WXLunaSoftKeyPanel::~WXLunaSoftKeyPanel() +WXSoftKeyPanel::~WXSoftKeyPanel() { } // フォントサイズ変更 (外部インタフェース) void -WXLunaSoftKeyPanel::SetFontSize(fontsize_t new_fontsize) +WXSoftKeyPanel::SetFontSize(FontId new_fontid) { // 同じなら何もしない - if (fontsize == new_fontsize) { + if (fontid == new_fontid) { return; } // フォントを更新 - UpdateFont(new_fontsize); + UpdateFont(new_fontid); // サイズ変更処理 DoSize(); @@ -62,39 +84,42 @@ WXLunaSoftKeyPanel::SetFontSize(fontsize // ここではサイズは fontsize にのみ依存しているので、フォントサイズが // 変化/確定した時に呼び出すこと。 void -WXLunaSoftKeyPanel::DoSize() +WXSoftKeyPanel::DoSize() { - assert(fontsize != FONT_NONE); + assert(fontid != FontId::None); // このパネル内の描画の基本単位 unit = font_height / 4; // エンターキーだけ矩形でないのでここでリージョンを計算。 // unit が確定したところで一回行う。 + // ただし SHIFT_R のキーコードはちょっと使いづらいので、ここでは SHIFT_R + // を使わず [_] キーで代用する。 + // + // | ^ | \ | BS | + // | | | | + // --+---+---+--(A)--+------(B) + // | | | + // | [ | | + // | | Enter | + // --+---+---+--(F)-(E) | + // | | | | + // | : | ] | | + // | | | | + // --+---+---+------(D)-----(C) + // | | + // _ | SHIFT | // - // | ^ | \ | BS | - // | | | | - // +---+---+--(A)--+------(B) - // | | | - // | [ | | - // | | Enter | - // +---+---+--(F)-(E) | - // | | | | - // | : | ] | | - // | | | | - // +---+---+------(D)-----(C) - // | | - // | SHIFT | const keydata_t& keybs = FindKeydata(KC_BS); const keydata_t& keyleft = FindKeydata(KC_bracketleft); const keydata_t& keyright = FindKeydata(KC_bracketright); - const keydata_t& keyshift = FindKeydata(KC_SHIFT_R); + const keydata_t& keyscore = FindKeydata(KC_underscore); // 各点のピクセル座標 enter_points = { { keyleft.right() * unit, keyleft.y * unit }, // A { keybs.right() * unit, keyleft.y * unit }, // B - { keyshift.right() * unit, keyshift.y * unit }, // C - { keyright.right() * unit, keyshift.y * unit }, // D + { keybs.right() * unit, keyscore.y * unit }, // C + { keyright.right() * unit, keyscore.y * unit }, // D { keyright.right() * unit, keyright.y * unit }, // E { keyleft.right() * unit, keyright.y * unit }, // F }; @@ -102,97 +127,76 @@ WXLunaSoftKeyPanel::DoSize() enter_region = wxRegion(enter_points.size(), enter_points.data()); // コントロールの大きさを変更 - wxSize size(228 * unit, 54 * unit); + wxSize size(u_width * unit, u_height * unit); SetClientSize(size); - SetMinSize(size); + SetMinClientSize(size); } // サイズ変更イベント void -WXLunaSoftKeyPanel::OnSize(wxSizeEvent& event) +WXSoftKeyPanel::OnSize(wxSizeEvent& event) { // Mac ではウィンドウ作成時に 0 以下の値が来ることがある // GTK では 1 で来ることがある - wxSize size = event.GetSize(); + const wxSize& size = event.GetSize(); if (size.x <= 1 || size.y <= 1) { return; } - view_width = size.x; - view_height = size.y; - - // ビットマップを持っていれば一旦解放 - if (bitmap) { - delete bitmap; - bitmap = NULL; - } - if (image) { - delete image; - image = NULL; - } - if (bmpbuf) { - delete bmpbuf; - bmpbuf = NULL; - } - // ビットマップ作成 - // 正しく描かれなかった時に分かりやすいよう初期値は濃いグレーにしておく - bmpbuf = new uint8 [view_width * view_height * 3]; - memset(bmpbuf, 0x70, view_width * view_height * 3); - image = new wxImage(view_width, view_height, bmpbuf, true); - bitmap = new wxBitmap(*image); + bitmap.Create(size.x, size.y); // 再描画を指示 Refresh(); } +// タイマーイベント +void +WXSoftKeyPanel::OnTimer(wxTimerEvent& event) +{ + // 更新があれば再描画を指示 + const std::vector& pressed = gKeyboard->GetPressed(); + UpdateModifier(); + if (pressed != last_pressed || modifier != last_modifier) { + Refresh(); + } +} + // 描画イベント (UI スレッドから呼ばれる) void -WXLunaSoftKeyPanel::OnPaint(wxPaintEvent& event) +WXSoftKeyPanel::OnPaint(wxPaintEvent& event) { // メモリ DC に描画 wxMemoryDC memDC; - memDC.SelectObject(*bitmap); + memDC.SelectObject(bitmap); Draw(memDC); // 実画面 DC にコピー wxPaintDC dstDC(this); - dstDC.Blit(0, 0, view_width, view_height, &memDC, 0, 0); + wxSize size = bitmap.GetSize(); + dstDC.Blit(0, 0, size.x, size.y, &memDC, 0, 0); } // 描画本体 void -WXLunaSoftKeyPanel::Draw(wxDC& dc) +WXSoftKeyPanel::Draw(wxDC& dc) { - wxColour fgcolor; // 前景色 - wxColour bgcolor; // 背景というかガワの色 - wxColour keydown_color = UD_BLUE; // キーが押された時の色 - - if (black_keyboard) { - fgcolor = *wxWHITE; - bgcolor = *wxBLACK; - } else { - fgcolor = *wxBLACK; - bgcolor = GetTextBackColor(); - } - - // 新品現物のガワは何色だったんだろう - dc.SetPen(wxPen(bgcolor)); - dc.SetBrush(wxBrush(bgcolor)); + dc.SetPen(wxPen(color.Background)); + dc.SetBrush(wxBrush(color.Background)); dc.DrawRectangle(wxPoint(0, 0), GetSize()); - dc.SetPen(fgcolor); - SetTextForeColor(fgcolor); + dc.SetPen(color.Text); + SetTextForeColor(color.Text); for (const auto& key : keydata) { - if (hit[key.keycode]) { + bool is_pressed = gKeyboard->IsPressed(key.keycode); + if (is_pressed) { // 押されている - SetTextBackColor(keydown_color); - dc.SetBrush(keydown_color); + SetTextBackColor(color.KeyPressed); + dc.SetBrush(color.KeyPressed); } else { // 押されていない - const wxColour& keytop = GetTopColor(key); - SetTextBackColor(keytop); - dc.SetBrush(wxBrush(keytop)); + SetTextBackColor(color.Keytop[key.coltype]); + dc.SetBrush(wxBrush(color.Keytop[key.coltype])); } // エンターキーだけ枠の描き方が違うので別処理 @@ -201,17 +205,26 @@ WXLunaSoftKeyPanel::Draw(wxDC& dc) } else { DrawKey(dc, key); } + + // 次回更新チェック用に現状を保存 + last_pressed[key.keycode] = is_pressed; } - SetTextBackColor(bgcolor); - wxString utfstr("右クリックで長押し"); + // 次回更新チェック用に現状を保存 + last_modifier = modifier; + +#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 -WXLunaSoftKeyPanel::DrawKey(wxDC& dc, const keydata_t& key) +WXSoftKeyPanel::DrawKey(wxDC& dc, const keydata_t& key) { // 枠 wxPoint pt(key.x * unit, key.y * unit); @@ -227,51 +240,59 @@ WXLunaSoftKeyPanel::DrawKey(wxDC& dc, co // Shift_JIS に変換 wxString utfstr(disp, wxConvUTF8); const char *sjis = (const char *)utfstr.mb_str(conv); - // Shift_JIS での文字数なので半角換算の文字数と一致する。 - int sjislen = strlen(sjis); + // 改行があれば2行に分割 + char sjis1[8] {}; + char sjis2[8] {}; + int sjislen; + int row; + const char *lf = strchr(sjis, '\n'); + if (lf == NULL) { + // 1行なら、Shift_JIS での文字数は半角換算の文字数と一致する。 + sjislen = strlen(sjis); + row = 1; + } else { + // 2行に分割。センタリングは1行目の長さだけで調べる。 + strncpy(sjis1, sjis, lf - sjis); + strcpy(sjis2, lf + 1); + sjislen = strlen(sjis1); + row = 2; + } // センタリング int x = key.x + (key.w - sjislen * 2) / 2; - int y = key.y + (key.h - 4) / 2; - // 「CAP」と「KANA」は LED 付き - if (IsLEDKey(key.keycode)) { - bool led = (key.keycode == KC_CAPS) - ? led_cap - : led_kana; + int y = key.y + (key.h - row * 4) / 2; + // LED を描画 (機種によって色々違うので個別クラス側で処理) + if (key.led >= 0) { const wxPen oldpen = dc.GetPen(); const wxBrush oldbrush = dc.GetBrush(); - if (led) { - // 点灯時は赤、枠は黒 - dc.SetPen(*wxBLACK); - dc.SetBrush(UD_RED); - } else { - // 消灯時は元のキートップの色で、枠は薄めにしたい - dc.SetPen(GetTextDisableColor()); - dc.SetBrush(GetTopColor(key)); - } - dc.DrawRectangle( - wxPoint(key.x * unit + 2, key.y * unit + 2), - wxSize(4 * unit - 2, 3 * unit - 2)); + + y += DrawLED(dc, key); + dc.SetPen(oldpen); dc.SetBrush(oldbrush); - - // LED を描くため文字を少し下げる - y += 1; } // 文字を描画 pt = wxPoint(x * unit + 1, y * unit + 1); - if (key.keycode == KC_PAD_enter) { + if (strcmp(disp, EnterMark) == 0) { DrawEnterMark(dc, pt); } else { - DrawStringSJIS(dc, pt.x, pt.y, sjis); + if (lf == NULL) { + // 1行の場合 + DrawStringSJIS(dc, pt.x, pt.y, sjis); + } else { + // 2行の場合 + DrawStringSJIS(dc, pt.x, pt.y, sjis1); + pt.y += 4 * unit; + DrawStringSJIS(dc, pt.x, pt.y, sjis2); + } } } // エンターキー void -WXLunaSoftKeyPanel::DrawEnterKey(wxDC& dc) +WXSoftKeyPanel::DrawEnterKey(wxDC& dc) { // エンターキーを描画 dc.DrawPolygon(enter_points.size(), enter_points.data()); @@ -286,7 +307,7 @@ WXLunaSoftKeyPanel::DrawEnterKey(wxDC& d // メインキーとテンキーの両方で同じ図柄を使う。 // 大きさは (3unit, 4unit) なので実質全角1文字分くらい。 void -WXLunaSoftKeyPanel::DrawEnterMark(wxDC& dc, const wxPoint& basep) +WXSoftKeyPanel::DrawEnterMark(wxDC& dc, const wxPoint& basep) { // エンター記号は幅 3 unit、高さ 4 unit。 // +0 +1 +2 +3 @@ -317,32 +338,9 @@ WXLunaSoftKeyPanel::DrawEnterMark(wxDC& } } -// キートップの色を返す。 -const wxColour -WXLunaSoftKeyPanel::GetTopColor(const keydata_t& key) const -{ - // 濃いキートップに UD_GREY は濃すぎるので薄めた色を使う。 - // ここは濃淡で見分けを付けたいわけではなくてただのデザインなので。 - if (key.coltype == 0) { - // 薄いキートップ - if (black_keyboard) { - return wxColour(50, 50, 53); - } else { - return *wxWHITE; - } - } else { - // 濃いキートップ - if (black_keyboard) { - return *wxBLACK; - } else { - return wxColour(200, 200, 203); - } - } -} - // keycode に対応する keydata を返す const keydata_t& -WXLunaSoftKeyPanel::FindKeydata(uint keycode) const +WXSoftKeyPanel::FindKeydata(uint keycode) const { for (const auto& key : keydata) { if (key.keycode == keycode) { @@ -350,59 +348,51 @@ WXLunaSoftKeyPanel::FindKeydata(uint key } } // 見付からないはずはない - warnx("keycode %d not found", keycode); - assert(true); - __unreachable(); + assertmsg(0, "keycode %d not found", keycode); } // マウス左クリック (Down) イベント void -WXLunaSoftKeyPanel::OnLeftDown(wxMouseEvent& event) +WXSoftKeyPanel::OnLeftDown(wxMouseEvent& event) { - wxPoint pt = event.GetPosition(); - uint code = GetKeycodeFromPoint(pt); + const wxPoint& pt = event.GetPosition(); + const keydata_t *key = GetKeydataFromPoint(pt); - DoLeftDown(code); + DoLeftDown(key); } // マウス左クリック (Down) 処理 void -WXLunaSoftKeyPanel::DoLeftDown(uint code) +WXSoftKeyPanel::DoLeftDown(const keydata_t *key) { - if (code != 0) { - if (hit[code]) { - // 押下(長押し)中のキーならここで開放 - KeyUp(code); - } else { - // 押下して、LeftUp のために覚えておく - KeyDown(code); - leftdown_keycode = code; - } + if (key != NULL) { + // 押下 + KeyDown(*key); + // LeftUp のために覚えておく + leftdown_key = key; } } // マウス左クリック (Up) イベント void -WXLunaSoftKeyPanel::OnLeftUp(wxMouseEvent& event) +WXSoftKeyPanel::OnLeftUp(wxMouseEvent& event) { // Up 時は、これが起きた地点のキーコードではなく // 直近に LeftDown したキーコードをターゲットにする。 - uint code = leftdown_keycode; + const keydata_t *key = leftdown_key; - DoLeftUp(code); + DoLeftUp(key); } // マウス左クリック (Up) 処理 void -WXLunaSoftKeyPanel::DoLeftUp(uint code) +WXSoftKeyPanel::DoLeftUp(const keydata_t *key) { - if (code != 0) { - // 押されていたら開放 - if (hit[code]) { - KeyUp(code); - } + if (key != NULL) { + // 開放 + KeyUp(*key); } - leftdown_keycode = 0; + leftdown_key = NULL; } // マウス左ダブルクリックイベント @@ -416,115 +406,197 @@ WXLunaSoftKeyPanel::DoLeftUp(uint code) // 直接 EVT_LEFT_DCLICK => OnLeftDown に割り付けることも出来そうだが // デバッグが紛らわしくなりそうなので独立したイベントとしておく。 void -WXLunaSoftKeyPanel::OnLeftDClick(wxMouseEvent& event) +WXSoftKeyPanel::OnLeftDClick(wxMouseEvent& event) { - wxPoint pt = event.GetPosition(); - uint code = GetKeycodeFromPoint(pt); + const wxPoint& pt = event.GetPosition(); + const keydata_t *key = GetKeydataFromPoint(pt); - DoLeftDown(code); + DoLeftDown(key); } // マウス右クリック (Down) イベント // 長押し開始/解除。 // 右クリックのほうは Down だけで Up は使わない。 void -WXLunaSoftKeyPanel::OnRightDown(wxMouseEvent& event) +WXSoftKeyPanel::OnRightDown(wxMouseEvent& event) { - wxPoint pt = event.GetPosition(); - uint code = GetKeycodeFromPoint(pt); + const wxPoint& pt = event.GetPosition(); + const keydata_t *key = GetKeydataFromPoint(pt); - if (code != 0) { - if (hit[code]) { + if (key != NULL) { + uint code = key->keycode; + if (gKeyboard->IsPressed(code)) { // 押されていたら開放 - KeyUp(code); + KeyUp(*key); } else { // 押されてなければ長押し開始 - KeyDown(code); + KeyDown(*key); } } } -// このキーが押された処理 -void -WXLunaSoftKeyPanel::KeyDown(uint code) +// 座標からキーデータを返す。 +// キーに当たっていなければ NULL を返す。 +const keydata_t * +WXSoftKeyPanel::GetKeydataFromPoint(const wxPoint& pt) const { - // 押された - hit[code] = true; + // エンターキーだけ先に別判定 + if (enter_region.Contains(pt) == wxInRegion) { + return &FindKeydata(KC_enter); + } - // LED キーは押下時に変化(反転)させて、その結果 - // 点灯なら Make、消灯なら Break を送信。 - if (code == KC_CAPS) { - led_cap = !led_cap; - if (led_cap) { - gKeyboard->MakeKey(code); - } else { - gKeyboard->BreakKey(code); + for (const auto& key : keydata) { + if (key.x < 0) { + continue; } - } else if (code == KC_kana) { - led_kana = !led_kana; - if (led_kana) { - gKeyboard->MakeKey(code); - } else { - gKeyboard->BreakKey(code); + // 始点と幅の +1/-1 は罫線の分 + wxRect rect( + (key.x * unit) + 1, + (key.y * unit) + 1, + (key.w * unit) - 1, + (key.h * unit) - 1); + if (rect.Contains(pt)) { + return &key; } + } + return NULL; +} + +// 修飾キーなら true を返す +// (今は SHIFT しかないから修飾キーならなのか SHIFT ならなのか曖昧) +bool +WXSoftKeyPanel::IsModifier(uint code) const +{ + if (code == KC_SHIFT_L || code == KC_SHIFT_R || code == KC_SHIFT) { + return true; } else { - // 通常キーは押下で Make 送信。 - gKeyboard->MakeKey(code); + return false; } +} - // 修飾キー - if (code == KC_SHIFT_L || code == KC_SHIFT_R) { +// 修飾キーの状態を更新。今は SHIFT かどうかしかない +void +WXSoftKeyPanel::UpdateModifier() +{ + if (gKeyboard->IsShift()) { modifier = ModShift; + } else { + modifier = ModNormal; + } +} + +// このキーが押された処理 +void +WXSoftKeyPanel::KeyDown(const keydata_t& key) +{ + uint code = key.keycode; + + // VM に通知 (Keyboard がそれをホストに通知するかはまた別) + gKeyboard->MakeKey(code); + + // 修飾キー + if (IsModifier(code)) { + UpdateModifier(); } // キー状態が変わった(かも知れない)ので再描画 + // 押した時にはタイマーを待たずに再描画したほうがよかろう Refresh(); } // このキーが放された処理 void -WXLunaSoftKeyPanel::KeyUp(uint code) +WXSoftKeyPanel::KeyUp(const keydata_t& key) { - hit[code] = false; - // 通常キーなら Break を送る。(LED キーは KeyDown で送っているので不要) - if (!IsLEDKey(code)) { - gKeyboard->BreakKey(code); - } + uint code = key.keycode; + + // VM に通知 (Keyboard がそれをホストに通知するかはまた別) + gKeyboard->BreakKey(code); // 修飾キー - if (code == KC_SHIFT_L || code == KC_SHIFT_R) { - modifier = ModNormal; + if (IsModifier(code)) { + UpdateModifier(); } - // キー状態が変わった(かも知れない)ので再描画 - Refresh(); + // キー状態が変わった(かも知れない)が、 + // 解放時はタイマーに任せた再描画でよかろう + //Refresh(); } -// 座標からキーコード(KC_*)を返す。 -// キーに当たっていなければ KC_none を返す。 -uint -WXLunaSoftKeyPanel::GetKeycodeFromPoint(const wxPoint& pt) const + +// +// LUNA ソフトウェアキーボード (パネル) +// + +// コンストラクタ +WXLunaSoftKeyPanel::WXLunaSoftKeyPanel(wxWindow *parent) + : inherited(parent, keydata, 226, 54) { - // エンターキーだけ先に別判定 - if (enter_region.Contains(pt) == wxInRegion) { - return KC_enter; + // LUNA では + // BS キーの左隣 (0x5c) は円記号ではなくバックスラッシュ。 + // それを SHIFT したやつ(0x7c) は破線でないパイプ。 + // そのもう一つ左隣 (0x7e) はオーバーラインではなくチルダ。 + SetGlyph5C(true); + SetGlyph7E(true); + + // キートップの濃淡はユニバーサルデザインの推奨色ではないけど + // ここは見分けを付けるためではなくただのデザインなので。 + if (1) { + // 白モデル + color = { + .Background = UD_LIGHT_GREY, // 現物新品は何色だったんだろう + .Text = *wxBLACK, + .Keytop = { *wxWHITE, wxColour(200, 200, 203) }, + // 白黒共通 + .KeyPressed = UD_BLUE, + .Border = *wxBLACK, + .LED = { UD_RED }, + }; + } else { + // 黒モデル + color = { + .Background = *wxBLACK, + .Text = *wxWHITE, + .Keytop = { wxColour(50, 50, 53), *wxBLACK }, + // 白黒共通 + .KeyPressed = UD_BLUE, + .Border = *wxBLACK, + .LED = { UD_RED }, + }; } - for (const auto& key : keydata) { - if (key.x == -1) { - continue; - } - // 始点と幅の +1/-1 は罫線の分 - wxRect rect( - (key.x * unit) + 1, - (key.y * unit) + 1, - (key.w * unit) - 1, - (key.h * unit) - 1); - if (rect.Contains(pt)) { - return key.keycode; - } + DoSize(); +} + +// デストラクタ +WXLunaSoftKeyPanel::~WXLunaSoftKeyPanel() +{ +} + +// LED を描画して刻印描画のための y offset を返す。 +int +WXLunaSoftKeyPanel::DrawLED(wxDC& dc, const keydata_t& key) +{ + const std::vector& led = gKeyboard->GetLED(); + + if (led[key.led]) { + // 点灯時は赤、枠は黒 + dc.SetPen(color.Border); + dc.SetBrush(color.LED[0]); + } else { + // 消灯時は元のキートップの色で、枠は薄めにしたい + // (枠の色は今の所全モデル共通なので ColorPalette に含めていない) + dc.SetPen(UD_GREY); + dc.SetBrush(color.Keytop[key.coltype]); } - return KC_none; + + // LED を左肩に描く + wxPoint pt = wxPoint(key.x * unit + 2, key.y * unit + 2); + wxSize sz = wxSize(4 * unit - 2, 3 * unit - 2); + dc.DrawRectangle(pt, sz); + + // そのため文字は少し下げる + return +1; } // キーデータ @@ -535,157 +607,349 @@ WXLunaSoftKeyPanel::GetKeycodeFromPoint( #define L3 (28) // CTRL の行 #define L4 (36) // SHIFT の行 #define L5 (44) // space の行 -// エンター記号は半角2文字幅なので空白2個で表現しておく。 -// 文字数から文字幅をカウントするのに使っているだけで、描画には使わない。 -#define EnterMark " " /*static*/ std::vector WXLunaSoftKeyPanel::keydata { - // +--- キートップの色種別(0:薄い 1:濃い) - // | - // X Y W H C KeyCode 通常 SHIFT - { 2, L0, 15, H, 1, KC_F1, { "PF1" } }, - { 17, L0, 15, H, 1, KC_F2, { "PF2" } }, - { 32, L0, 15, H, 1, KC_F3, { "PF3" } }, - { 47, L0, 15, H, 1, KC_F4, { "PF4" } }, - { 62, L0, 15, H, 1, KC_F5, { "PF5" } }, - { 81, L0, 15, H, 1, KC_F6, { "PF6" } }, - { 96, L0, 15, H, 1, KC_F7, { "PF7" } }, - { 111, L0, 15, H, 1, KC_F8, { "PF8" } }, - { 126, L0, 15, H, 1, KC_F9, { "PF9" } }, - { 141, L0, 15, H, 1, KC_F10, { "PF10" } }, - - { 2, L1, 12, H, 1, KC_ESC, { "ESC" } }, - { 14, L1, 10, H, 0, KC_1, { "1", "!" } }, - { 24, L1, 10, H, 0, KC_2, { "2", "\"" } }, - { 34, L1, 10, H, 0, KC_3, { "3", "#" } }, - { 44, L1, 10, H, 0, KC_4, { "4", "$" } }, - { 54, L1, 10, H, 0, KC_5, { "5", "%" } }, - { 64, L1, 10, H, 0, KC_6, { "6", "&" } }, - { 74, L1, 10, H, 0, KC_7, { "7", "'" } }, - { 84, L1, 10, H, 0, KC_8, { "8", "(" } }, - { 94, L1, 10, H, 0, KC_9, { "9", ")" } }, - { 104, L1, 10, H, 0, KC_0, { "0", " " } }, - { 114, L1, 10, H, 0, KC_minus, { "-", "=" } }, - { 124, L1, 10, H, 0, KC_circum, { "^", "~" } }, - { 134, L1, 10, H, 0, KC_backslash, { "\\", "|" } }, - { 144, L1, 12, H, 1, KC_BS, { "BS" } }, - - { 2, L2, 17, H, 1, KC_TAB, { "TAB" } }, - { 19, L2, 10, H, 0, KC_Q, { "q", "Q" } }, - { 29, L2, 10, H, 0, KC_W, { "w", "W" } }, - { 39, L2, 10, H, 0, KC_E, { "e", "E" } }, - { 49, L2, 10, H, 0, KC_R, { "r", "R" } }, - { 59, L2, 10, H, 0, KC_T, { "t", "T" } }, - { 69, L2, 10, H, 0, KC_Y, { "y", "Y" } }, - { 79, L2, 10, H, 0, KC_U, { "u", "U" } }, - { 89, L2, 10, H, 0, KC_I, { "i", "I" } }, - { 99, L2, 10, H, 0, KC_O, { "o", "O" } }, - { 109, L2, 10, H, 0, KC_P, { "p", "P" } }, - { 119, L2, 10, H, 0, KC_at, { "@", "`" } }, - { 129, L2, 10, H, 0, KC_bracketleft, { "[", "{" } }, - - { 2, L3, 20, H, 1, KC_CTRL, { "CTRL" } }, - { 22, L3, 10, H, 0, KC_A, { "a", "A" } }, - { 32, L3, 10, H, 0, KC_S, { "s", "S" } }, - { 42, L3, 10, H, 0, KC_D, { "d", "D" } }, - { 52, L3, 10, H, 0, KC_F, { "f", "F" } }, - { 62, L3, 10, H, 0, KC_G, { "g", "G" } }, - { 72, L3, 10, H, 0, KC_H, { "h", "H" } }, - { 82, L3, 10, H, 0, KC_J, { "j", "J" } }, - { 92, L3, 10, H, 0, KC_K, { "k", "K" } }, - { 102, L3, 10, H, 0, KC_L, { "l", "L" } }, - { 112, L3, 10, H, 0, KC_semicolon, { ";", "+" } }, - { 122, L3, 10, H, 0, KC_colon, { ":", "*" } }, - { 132, L3, 10, H, 0, KC_bracketright, { "]", "}" } }, - - { 2, L4, 25, H, 1, KC_SHIFT_L, { "SHIFT" } }, - { 27, L4, 10, H, 0, KC_Z, { "z", "Z" } }, - { 37, L4, 10, H, 0, KC_X, { "x", "X" } }, - { 47, L4, 10, H, 0, KC_C, { "c", "C" } }, - { 57, L4, 10, H, 0, KC_V, { "v", "V" } }, - { 67, L4, 10, H, 0, KC_B, { "b", "B" } }, - { 77, L4, 10, H, 0, KC_N, { "n", "N" } }, - { 87, L4, 10, H, 0, KC_M, { "m", "M" } }, - { 97, L4, 10, H, 0, KC_comma, { ",", "<" } }, - { 107, L4, 10, H, 0, KC_period, { ".", ">" } }, - { 117, L4, 10, H, 0, KC_slash, { "/", "?" } }, - { 127, L4, 10, H, 0, KC_underscore, { " ", "_" } }, - { 137, L4, 19, H, 1, KC_SHIFT_R, { "SHIFT" } }, - - { 2, L5, 20, H, 1, KC_VALID, { "確定" } }, - { 22, L5, 10, H, 1, KC_SF, { "前面" } }, - { 32, L5, 10, H, 1, KC_CAPS, { "CAP" } }, - { 42, L5, 80, H, 0, KC_space, { " " } }, - { 122, L5, 10, H, 1, KC_kana, { "かな" } }, - { 132, L5, 24, H, 1, KC_XFER, { "変換" } }, + // +---- キートップの色(1:濃) + // | +- 0 以上なら LED 番号 + // X Y W H C L KeyCode 通常 SHIFT + { 2, L0, 15, H, 1,-1, KC_F1, { "PF1" } }, + { 17, L0, 15, H, 1,-1, KC_F2, { "PF2" } }, + { 32, L0, 15, H, 1,-1, KC_F3, { "PF3" } }, + { 47, L0, 15, H, 1,-1, KC_F4, { "PF4" } }, + { 62, L0, 15, H, 1,-1, KC_F5, { "PF5" } }, + { 81, L0, 15, H, 1,-1, KC_F6, { "PF6" } }, + { 96, L0, 15, H, 1,-1, KC_F7, { "PF7" } }, + { 111, L0, 15, H, 1,-1, KC_F8, { "PF8" } }, + { 126, L0, 15, H, 1,-1, KC_F9, { "PF9" } }, + { 141, L0, 15, H, 1,-1, KC_F10, { "PF10" } }, + + { 2, L1, 12, H, 1,-1, KC_ESC, { "ESC" } }, + { 14, L1, 10, H, 0,-1, KC_1, { "1", "!" } }, + { 24, L1, 10, H, 0,-1, KC_2, { "2", "\"" } }, + { 34, L1, 10, H, 0,-1, KC_3, { "3", "#" } }, + { 44, L1, 10, H, 0,-1, KC_4, { "4", "$" } }, + { 54, L1, 10, H, 0,-1, KC_5, { "5", "%" } }, + { 64, L1, 10, H, 0,-1, KC_6, { "6", "&" } }, + { 74, L1, 10, H, 0,-1, KC_7, { "7", "'" } }, + { 84, L1, 10, H, 0,-1, KC_8, { "8", "(" } }, + { 94, L1, 10, H, 0,-1, KC_9, { "9", ")" } }, + { 104, L1, 10, H, 0,-1, KC_0, { "0", " " } }, + { 114, L1, 10, H, 0,-1, KC_minus, { "-", "=" } }, + { 124, L1, 10, H, 0,-1, KC_circum, { "^", "~" } }, + { 134, L1, 10, H, 0,-1, KC_backslash, { "\\", "|" } }, + { 144, L1, 12, H, 1,-1, KC_BS, { "BS" } }, + + { 2, L2, 17, H, 1,-1, KC_TAB, { "TAB" } }, + { 19, L2, 10, H, 0,-1, KC_Q, { "q", "Q" } }, + { 29, L2, 10, H, 0,-1, KC_W, { "w", "W" } }, + { 39, L2, 10, H, 0,-1, KC_E, { "e", "E" } }, + { 49, L2, 10, H, 0,-1, KC_R, { "r", "R" } }, + { 59, L2, 10, H, 0,-1, KC_T, { "t", "T" } }, + { 69, L2, 10, H, 0,-1, KC_Y, { "y", "Y" } }, + { 79, L2, 10, H, 0,-1, KC_U, { "u", "U" } }, + { 89, L2, 10, H, 0,-1, KC_I, { "i", "I" } }, + { 99, L2, 10, H, 0,-1, KC_O, { "o", "O" } }, + { 109, L2, 10, H, 0,-1, KC_P, { "p", "P" } }, + { 119, L2, 10, H, 0,-1, KC_at, { "@", "`" } }, + { 129, L2, 10, H, 0,-1, KC_bracketleft, { "[", "{" } }, + + { 2, L3, 20, H, 1,-1, KC_CTRL, { "CTRL" } }, + { 22, L3, 10, H, 0,-1, KC_A, { "a", "A" } }, + { 32, L3, 10, H, 0,-1, KC_S, { "s", "S" } }, + { 42, L3, 10, H, 0,-1, KC_D, { "d", "D" } }, + { 52, L3, 10, H, 0,-1, KC_F, { "f", "F" } }, + { 62, L3, 10, H, 0,-1, KC_G, { "g", "G" } }, + { 72, L3, 10, H, 0,-1, KC_H, { "h", "H" } }, + { 82, L3, 10, H, 0,-1, KC_J, { "j", "J" } }, + { 92, L3, 10, H, 0,-1, KC_K, { "k", "K" } }, + { 102, L3, 10, H, 0,-1, KC_L, { "l", "L" } }, + { 112, L3, 10, H, 0,-1, KC_semicolon, { ";", "+" } }, + { 122, L3, 10, H, 0,-1, KC_colon, { ":", "*" } }, + { 132, L3, 10, H, 0,-1, KC_bracketright, { "]", "}" } }, + + { 2, L4, 25, H, 1,-1, KC_SHIFT_L, { "SHIFT" } }, + { 27, L4, 10, H, 0,-1, KC_Z, { "z", "Z" } }, + { 37, L4, 10, H, 0,-1, KC_X, { "x", "X" } }, + { 47, L4, 10, H, 0,-1, KC_C, { "c", "C" } }, + { 57, L4, 10, H, 0,-1, KC_V, { "v", "V" } }, + { 67, L4, 10, H, 0,-1, KC_B, { "b", "B" } }, + { 77, L4, 10, H, 0,-1, KC_N, { "n", "N" } }, + { 87, L4, 10, H, 0,-1, KC_M, { "m", "M" } }, + { 97, L4, 10, H, 0,-1, KC_comma, { ",", "<" } }, + { 107, L4, 10, H, 0,-1, KC_period, { ".", ">" } }, + { 117, L4, 10, H, 0,-1, KC_slash, { "/", "?" } }, + { 127, L4, 10, H, 0,-1, KC_underscore, { " ", "_" } }, + { 137, L4, 19, H, 1,-1, KC_SHIFT_R, { "SHIFT" } }, + + { 2, L5, 20, H, 1,-1, KC_VALID, { "確定" } }, + { 22, L5, 10, H, 1,-1, KC_SF, { "前面" } }, + { 32, L5, 10, H, 1, 1, KC_CAPS, { "CAP" } }, + { 42, L5, 80, H, 0,-1, KC_space, { " " } }, + { 122, L5, 10, H, 1, 0, KC_kana, { "かな" } }, + { 132, L5, 24, H, 1,-1, KC_XFER, { "変換" } }, // カーソルキー島 - { 158, L1, 13, H, 1, KC_PF11, { "消去" } }, - { 171, L1, 13, H, 1, KC_PF12, { "呼出" } }, - { 158, L2, 13, H, 1, KC_PF13, { "文節←" } }, - { 171, L2, 13, H, 1, KC_PF14, { "文節→" } }, - { 158, L3, 26, H, 1, KC_up, { "↑" } }, - { 158, L4, 13, H, 1, KC_left, { "←" } }, - { 171, L4, 13, H, 1, KC_right, { "→" } }, - { 158, L5, 26, H, 1, KC_down, { "↓" } }, + { 160, L1, 10, H, 1,-1, KC_PF11, { "消去" } }, + { 170, L1, 10, H, 1,-1, KC_PF12, { "呼出" } }, + { 160, L2, 10, H, 1,-1, KC_PF13, { "文節\n←" } }, + { 170, L2, 10, H, 1,-1, KC_PF14, { "文節\n→" } }, + { 160, L3, 20, H, 1,-1, KC_up, { "↑" } }, + { 160, L4, 10, H, 1,-1, KC_left, { "←" } }, + { 170, L4, 10, H, 1,-1, KC_right, { "→" } }, + { 160, L5, 20, H, 1,-1, KC_down, { "↓" } }, // テンキー島 - { 186, L1, 10, H, 1, KC_DEL, { "DEL" } }, - { 196, L1, 10, H, 1, KC_PAD_plus, { "+" } }, - { 206, L1, 10, H, 1, KC_PAD_minus, { "-" } }, - { 216, L1, 10, H, 1, KC_PAD_multiply, { "*" } }, - - { 186, L2, 10, H, 0, KC_PAD_7, { "7" } }, - { 196, L2, 10, H, 0, KC_PAD_8, { "8" } }, - { 206, L2, 10, H, 0, KC_PAD_9, { "9" } }, - { 216, L2, 10, H, 1, KC_PAD_divide, { "/" } }, - - { 186, L3, 10, H, 0, KC_PAD_4, { "4" } }, - { 196, L3, 10, H, 0, KC_PAD_5, { "5" } }, - { 206, L3, 10, H, 0, KC_PAD_6, { "6" } }, - { 216, L3, 10, H, 1, KC_PAD_equal, { "=" } }, - - { 186, L4, 10, H, 0, KC_PAD_1, { "1" } }, - { 196, L4, 10, H, 0, KC_PAD_2, { "2" } }, - { 206, L4, 10, H, 0, KC_PAD_3, { "3" } }, - { 216, L4, 10, H, 1, KC_PAD_comma, { "," } }, - - { 186, L5, 10, H, 0, KC_PAD_0, { "0" } }, - { 196, L5, 10, H, 0, KC_PAD_decimal, { "." } }, - { 206, L5, 20, H, 1, KC_PAD_enter, { EnterMark } }, + { 184, L1, 10, H, 1,-1, KC_DEL, { "DEL" } }, + { 194, L1, 10, H, 1,-1, KC_PAD_plus, { "+" } }, + { 204, L1, 10, H, 1,-1, KC_PAD_minus, { "-" } }, + { 214, L1, 10, H, 1,-1, KC_PAD_multiply, { "*" } }, + + { 184, L2, 10, H, 0,-1, KC_PAD_7, { "7" } }, + { 194, L2, 10, H, 0,-1, KC_PAD_8, { "8" } }, + { 204, L2, 10, H, 0,-1, KC_PAD_9, { "9" } }, + { 214, L2, 10, H, 1,-1, KC_PAD_divide, { "/" } }, + + { 184, L3, 10, H, 0,-1, KC_PAD_4, { "4" } }, + { 194, L3, 10, H, 0,-1, KC_PAD_5, { "5" } }, + { 204, L3, 10, H, 0,-1, KC_PAD_6, { "6" } }, + { 214, L3, 10, H, 1,-1, KC_PAD_equal, { "=" } }, + + { 184, L4, 10, H, 0,-1, KC_PAD_1, { "1" } }, + { 194, L4, 10, H, 0,-1, KC_PAD_2, { "2" } }, + { 204, L4, 10, H, 0,-1, KC_PAD_3, { "3" } }, + { 214, L4, 10, H, 1,-1, KC_PAD_comma, { "," } }, + + { 184, L5, 10, H, 0,-1, KC_PAD_0, { "0" } }, + { 194, L5, 10, H, 0,-1, KC_PAD_decimal, { "." } }, + { 204, L5, 20, H, 1,-1, KC_PAD_enter, { EnterMark } }, // Enter だけ矩形でないので別処理するが // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。 - { -1, -1, -1, -1, 1, KC_enter, { EnterMark } }, + { -1, -1, -1, -1, 1,-1, KC_enter, { EnterMark } }, }; // -// LUNA ソフトウェアキーボード (ウィンドウ) +// X68k ソフトウェアキーボード (パネル) // // コンストラクタ -WXLunaSoftKeyWindow::WXLunaSoftKeyWindow(wxWindow *parent, wxWindowID id) - : inherited(parent, id, wxT("ソフトウェアキーボード")) +WXX68kSoftKeyPanel::WXX68kSoftKeyPanel(wxWindow *parent) + : inherited(parent, keydata, 235, 54) { - panel = new WXLunaSoftKeyPanel(this); + // X68k では SRAM 設定に同期させる。 + uint8 sw = gSRAM->Peek8(0xed0059); + SetGlyph5C((sw & 0x01)); + SetGlyph7E((sw & 0x02)); + SetGlyph7C((sw & 0x04)); + + // とりあえず黒のみ + color = { + .Background = wxColour(50, 50, 53), + .Text = *wxWHITE, + .Keytop = { *wxBLACK }, + .KeyPressed = UD_BLUE, + .Border = *wxBLACK, + .LED = { UD_RED, UD_YELLOW_GREEN }, + }; - // 大きさをそれに固定 - Layout(); - Fit(); + DoSize(); } // デストラクタ -WXLunaSoftKeyWindow::~WXLunaSoftKeyWindow() +WXX68kSoftKeyPanel::~WXX68kSoftKeyPanel() { } -// フォントサイズ変更 -void -WXLunaSoftKeyWindow::SetFontSize(fontsize_t fontsize) +// LED を描画して刻印描画のための y offset を返す。 +int +WXX68kSoftKeyPanel::DrawLED(wxDC& dc, const keydata_t& key) +{ + const std::vector& led = gKeyboard->GetLED(); + + // 色を選択 + // idx 刻印 色 + // ---------------- + // 0 かな 赤 + // 1 ローマ 赤 + // 2 コード 赤 + // 3 CAPS 赤 + // 4 INS 赤 + // 5 ひら 緑 + // 6 全角 緑 + if (led[key.led]) { + int n = (key.led < 5) ? 0 : 1; + dc.SetPen(color.LED[n]); + dc.SetBrush(color.LED[n]); + } else { + // 消灯時は元のキートップの色で、枠は薄めにしたい + // (枠の色は今の所全モデル共通なので ColorPalette に含めていない) + dc.SetPen(UD_GREY); + dc.SetBrush(color.Keytop[key.coltype]); + } + + // LED は中央前方(画面でいうと下) + wxPoint pt = wxPoint((key.x + 3) * unit, (key.y + key.h - 2) * unit); + wxSize sz = wxSize(4 * unit, 2 * unit); + dc.DrawRectangle(pt, sz); + + // そのため文字は少し上げる + return -1; +} + +#define LF (L0 + 2) // ファンクションキーは少し低い(横長い) +#define HT (H * 2) // 縦2倍角のキー +/*static*/ std::vector +WXX68kSoftKeyPanel::keydata { + // +- 0以上なら LED 番号 + // X Y W H C L KeyCode 通常 SHIFT + { 2, L0, 10, H, 0,-1, KC_BREAK, { "BRK" } }, + { 15, L0, 10, H, 0,-1, KC_COPY, { "COPY" } }, + { 29, LF, 12, 6, 0,-1, KC_F1, { "F1" } }, + { 41, LF, 12, 6, 0,-1, KC_F2, { "F2" } }, + { 53, LF, 12, 6, 0,-1, KC_F3, { "F3" } }, + { 65, LF, 12, 6, 0,-1, KC_F4, { "F4" } }, + { 77, LF, 13, 6, 0,-1, KC_F5, { "F5" } }, + { 94, LF, 13, 6, 0,-1, KC_F6, { "F6" } }, + { 106, LF, 12, 6, 0,-1, KC_F7, { "F7" } }, + { 118, LF, 12, 6, 0,-1, KC_F8, { "F8" } }, + { 130, LF, 12, 6, 0,-1, KC_F9, { "F9" } }, + { 142, LF, 13, 6, 0,-1, KC_F10, { "F10" } }, + + { 2, L1, 10, H, 0,-1, KC_ESC, { "ESC" } }, + { 12, L1, 10, H, 0,-1, KC_1, { "1", "!" } }, + { 22, L1, 10, H, 0,-1, KC_2, { "2", "\"" } }, + { 32, L1, 10, H, 0,-1, KC_3, { "3", "#" } }, + { 42, L1, 10, H, 0,-1, KC_4, { "4", "$" } }, + { 52, L1, 10, H, 0,-1, KC_5, { "5", "%" } }, + { 62, L1, 10, H, 0,-1, KC_6, { "6", "&" } }, + { 72, L1, 10, H, 0,-1, KC_7, { "7", "'" } }, + { 82, L1, 10, H, 0,-1, KC_8, { "8", "(" } }, + { 92, L1, 10, H, 0,-1, KC_9, { "9", ")" } }, + { 102, L1, 10, H, 0,-1, KC_0, { "0", " " } }, + { 112, L1, 10, H, 0,-1, KC_minus, { "-", "=" } }, + { 122, L1, 10, H, 0,-1, KC_circum, { "^", "~" } }, + { 132, L1, 10, H, 0,-1, KC_backslash, { "\\", "|" } }, + { 142, L1, 13, H, 0,-1, KC_BS, { "BS" } }, + + { 2, L2, 16, H, 0,-1, KC_TAB, { "TAB" } }, + { 18, L2, 10, H, 0,-1, KC_Q, { "q", "Q" } }, + { 28, L2, 10, H, 0,-1, KC_W, { "w", "W" } }, + { 38, L2, 10, H, 0,-1, KC_E, { "e", "E" } }, + { 48, L2, 10, H, 0,-1, KC_R, { "r", "R" } }, + { 58, L2, 10, H, 0,-1, KC_T, { "t", "T" } }, + { 68, L2, 10, H, 0,-1, KC_Y, { "y", "Y" } }, + { 78, L2, 10, H, 0,-1, KC_U, { "u", "U" } }, + { 88, L2, 10, H, 0,-1, KC_I, { "i", "I" } }, + { 98, L2, 10, H, 0,-1, KC_O, { "o", "O" } }, + { 108, L2, 10, H, 0,-1, KC_P, { "p", "P" } }, + { 118, L2, 10, H, 0,-1, KC_at, { "@", "`" } }, + { 128, L2, 10, H, 0,-1, KC_bracketleft, { "[", "{" } }, + + { 2, L3, 19, H, 0,-1, KC_CTRL, { "CTRL" } }, + { 21, L3, 10, H, 0,-1, KC_A, { "a", "A" } }, + { 31, L3, 10, H, 0,-1, KC_S, { "s", "S" } }, + { 41, L3, 10, H, 0,-1, KC_D, { "d", "D" } }, + { 51, L3, 10, H, 0,-1, KC_F, { "f", "F" } }, + { 61, L3, 10, H, 0,-1, KC_G, { "g", "G" } }, + { 71, L3, 10, H, 0,-1, KC_H, { "h", "H" } }, + { 81, L3, 10, H, 0,-1, KC_J, { "j", "J" } }, + { 91, L3, 10, H, 0,-1, KC_K, { "k", "K" } }, + { 101, L3, 10, H, 0,-1, KC_L, { "l", "L" } }, + { 111, L3, 10, H, 0,-1, KC_semicolon, { ";", "+" } }, + { 121, L3, 10, H, 0,-1, KC_colon, { ":", "*" } }, + { 131, L3, 10, H, 0,-1, KC_bracketright, { "]", "}" } }, + + { 2, L4, 24, H, 0,-1, KC_SHIFT, { "SHIFT" } }, + { 26, L4, 10, H, 0,-1, KC_Z, { "z", "Z" } }, + { 36, L4, 10, H, 0,-1, KC_X, { "x", "X" } }, + { 46, L4, 10, H, 0,-1, KC_C, { "c", "C" } }, + { 56, L4, 10, H, 0,-1, KC_V, { "v", "V" } }, + { 66, L4, 10, H, 0,-1, KC_B, { "b", "B" } }, + { 76, L4, 10, H, 0,-1, KC_N, { "n", "N" } }, + { 86, L4, 10, H, 0,-1, KC_M, { "m", "M" } }, + { 96, L4, 10, H, 0,-1, KC_comma, { ",", "<" } }, + { 106, L4, 10, H, 0,-1, KC_period, { ".", ">" } }, + { 116, L4, 10, H, 0,-1, KC_slash, { "/", "?" } }, + { 126, L4, 10, H, 0,-1, KC_underscore, { " ", "_" } }, + { 136, L4, 19, H, 0,-1, KC_SHIFT, { "SHIFT" } }, + + { 21, L5, 10, H, 0, 5, KC_hira, { "ひら" } }, + { 31, L5, 12, H, 0,-1, KC_XF1, { "XF1" } }, + { 43, L5, 13, H, 0,-1, KC_XF2, { "XF2" } }, + { 56, L5, 36, H, 0,-1, KC_space, { " " } }, + { 92, L5, 12, H, 0,-1, KC_XF3, { "XF3" } }, + { 104, L5, 12, H, 0,-1, KC_XF4, { "XF4" } }, + { 116, L5, 12, H, 0,-1, KC_XF5, { "XF5" } }, + { 128, L5, 10, H, 0, 6, KC_zenkaku, { "全角" } }, + + // カーソルキー島 + { 159, L0, 10, H, 0, 0, KC_kana, { "かな" } }, + { 169, L0, 10, H, 0, 1, KC_romaji, { "ローマ" } }, + { 179, L0, 10, H, 0, 2, KC_code, { "コード" } }, + { 159, L1, 10, H, 0,-1, KC_HOME, { "HOME" } }, + { 169, L1, 10, H, 0, 4, KC_INS, { "INS" } }, + { 179, L1, 10, H, 0,-1, KC_DEL, { "DEL" } }, + { 159, L2, 10, H, 0,-1, KC_ROLLUP, { "ROLL\n UP" } }, + { 169, L2, 10, H, 0,-1, KC_ROLLDOWN, { "ROLL\nDOWN" } }, + { 179, L2, 10, H, 0,-1, KC_UNDO, { "UNDO" } }, + { 169, L3, 10, H, 0,-1, KC_up, { "↑" } }, + { 159, L3, 10, HT,0,-1, KC_left, { "←" } }, + { 179, L3, 10, HT,0,-1, KC_right, { "→" } }, + { 169, L4, 10, H, 0,-1, KC_down, { "↓" } }, + { 159, L5, 15, H, 0,-1, KC_OPT1, { "OPT.1" } }, + { 174, L5, 15, H, 0,-1, KC_OPT2, { "OPT.2" } }, + + // テンキー島 + { 193, L0, 10, H, 0, 3, KC_CAPS, { "CAPS" } }, + { 203, L0, 10, H, 0,-1, KC_kigou, { "記号" } }, + { 213, L0, 10, H, 0,-1, KC_touroku, { "登録" } }, + { 223, L0, 10, H, 0,-1, KC_HELP, { "HELP" } }, + { 193, L1, 10, H, 0,-1, KC_PAD_CLR, { "CLR" } }, + { 203, L1, 10, H, 0,-1, KC_PAD_divide, { "/" } }, + { 213, L1, 10, H, 0,-1, KC_PAD_multiply, { "*" } }, + { 223, L1, 10, H, 0,-1, KC_PAD_minus, { "-" } }, + { 193, L2, 10, H, 0,-1, KC_PAD_7, { "7" } }, + { 203, L2, 10, H, 0,-1, KC_PAD_8, { "8" } }, + { 213, L2, 10, H, 0,-1, KC_PAD_9, { "9" } }, + { 223, L2, 10, H, 0,-1, KC_PAD_plus, { "+" } }, + { 193, L3, 10, H, 0,-1, KC_PAD_4, { "4" } }, + { 203, L3, 10, H, 0,-1, KC_PAD_5, { "5" } }, + { 213, L3, 10, H, 0,-1, KC_PAD_6, { "6" } }, + { 223, L3, 10, H, 0,-1, KC_PAD_equal, { "=" } }, + { 193, L4, 10, H, 0,-1, KC_PAD_1, { "1" } }, + { 203, L4, 10, H, 0,-1, KC_PAD_2, { "2" } }, + { 213, L4, 10, H, 0,-1, KC_PAD_3, { "3" } }, + { 223, L4, 10, HT,0,-1, KC_PAD_enter, { "ENT" } }, + { 193, L5, 10, H, 0,-1, KC_PAD_0, { "0" } }, + { 203, L5, 10, H, 0,-1, KC_PAD_comma, { "," } }, + { 213, L5, 10, H, 0,-1, KC_PAD_decimal, { "." } }, + + // Enter だけ矩形でないので別処理するが + // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。 + { -1, -1, -1, -1, 0,-1, KC_enter, { EnterMark } }, +}; + +// +// ソフトウェアキーボード (ウィンドウ) +// + +// コンストラクタ +WXSoftKeyWindow::WXSoftKeyWindow(wxWindow *parent, wxWindowID id, + vmtype_t vmtype) + : inherited(parent, id, _("Software Keyboard")) { - panel->SetFontSize(fontsize); - // 大きさ変更 - Layout(); + if (vmtype == VMTYPE_X68030) { + panel = new WXX68kSoftKeyPanel(this); + } else { + panel = new WXLunaSoftKeyPanel(this); + } + + // 大きさをそれに固定 Fit(); } + +// デストラクタ +WXSoftKeyWindow::~WXSoftKeyWindow() +{ +}