Annotation of nono/wx/wxsoftkey.cpp, revision 1.1.1.17

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.11  root        7: //
                      8: // ソフトウェアキーボード
                      9: //
                     10: 
1.1       root       11: #include "wxsoftkey.h"
1.1.1.11  root       12: #include "fontmanager.h"
1.1.1.13  root       13: #include "wxmainframe.h"
1.1.1.6   root       14: #include "wxmainview.h"
1.1.1.8   root       15: #include "wxuimessage.h"
1.1.1.4   root       16: #include "sram.h"
1.1       root       17: 
                     18: //
1.1.1.4   root       19: // ソフトウェアキーボード (パネル) 共通部分
1.1       root       20: //
                     21: 
1.1.1.4   root       22: // エンター記号。
                     23: // 描画の際にキー刻印文字列の半角文字数から描画幅を決定しており、
                     24: // エンター記号は半角2文字幅で描いているので実際の文字列も2文字にしておく。
                     25: // そうすると "\\n" が意味的にもちょうどいい。
                     26: // これは幅を算出するのに使うだけで表示はされない。
                     27: #define EnterMark      "\\n"
                     28: 
1.1       root       29: // イベントテーブル
1.1.1.4   root       30: wxBEGIN_EVENT_TABLE(WXSoftKeyPanel, inherited)
                     31:        EVT_LEFT_DOWN(WXSoftKeyPanel::OnLeftDown)
                     32:        EVT_LEFT_UP(WXSoftKeyPanel::OnLeftUp)
                     33:        EVT_LEFT_DCLICK(WXSoftKeyPanel::OnLeftDClick)
                     34:        EVT_RIGHT_DOWN(WXSoftKeyPanel::OnRightDown)
1.1.1.9   root       35:        EVT_TIMER(wxID_ANY, WXSoftKeyPanel::OnTimer)
1.1       root       36: wxEND_EVENT_TABLE()
                     37: 
                     38: // コンストラクタ
1.1.1.4   root       39: WXSoftKeyPanel::WXSoftKeyPanel(wxWindow *parent,
1.1.1.6   root       40:        const std::vector<keydata_t>& keydata_, int u_width_, int u_height_)
1.1       root       41:        : inherited(parent)
1.1.1.6   root       42:        , keydata(keydata_)
1.1       root       43: {
1.1.1.13  root       44:        // デバイスを取得
                     45:        keyboard = GetKeyboard();
                     46: 
1.1.1.9   root       47:        timer.SetOwner(this);
                     48: 
1.1.1.4   root       49:        u_width  = u_width_;
                     50:        u_height = u_height_;
1.1.1.6   root       51: 
1.1.1.11  root       52:        FontChanged();
1.1.1.7   root       53: 
1.1.1.10  root       54:        // トグル動作にするキー
                     55:        toggle.emplace(KC_SHIFT, 0);
                     56:        toggle.emplace(KC_SHIFT_L, 0);
                     57:        toggle.emplace(KC_SHIFT_R, 0);
                     58:        toggle.emplace(KC_CTRL, 0);
                     59: 
1.1.1.9   root       60:        // 残光の初期化。
                     61:        // persistence は keydata 分の配列ではなく共通キーコード分の配列。
                     62:        persistence.resize(KC_max);
                     63:        std::fill(persistence.begin(), persistence.end(), 0);
                     64: 
1.1.1.6   root       65:        // このパネルへのキー入力はメインビューへのキー入力と同じ。
1.1.1.13  root       66:        auto mainframe = dynamic_cast<WXMainFrame*>(GetParent()->GetParent());
                     67:        auto mainview = mainframe->GetMainView();
1.1.1.17! root       68:        Bind(wxEVT_CHAR,     &WXMainView::OnChar,    mainview);
        !            69:        Bind(wxEVT_KEY_UP,   &WXMainView::OnKeyUp,   mainview);
        !            70:        Bind(wxEVT_KEY_DOWN, &WXMainView::OnKeyDown, mainview);
1.1.1.6   root       71: 
1.1.1.8   root       72:        // VM からの通知を受け取る
                     73:        WXUIMessage::Connect(UIMessage::KEYBOARD, this,
                     74:                wxCommandEventHandler(WXSoftKeyPanel::OnKeyChanged));
1.1.1.11  root       75: 
                     76:        // 初期タイトルを保存しといて..
                     77:        title = dynamic_cast<wxFrame*>(parent)->GetTitle();
                     78:        // キーボードの接続状況でタイトルを更新する
                     79:        UpdateTitle();
1.1       root       80: }
                     81: 
                     82: // デストラクタ
1.1.1.4   root       83: WXSoftKeyPanel::~WXSoftKeyPanel()
1.1       root       84: {
1.1.1.10  root       85:        // ウィンドウクローズでトグルキーのワンショットは開放する
1.1.1.9   root       86:        // (長押しは開放しない)
1.1.1.10  root       87:        for (const auto& k : toggle) {
                     88:                auto code = k.second;
                     89:                if (code) {
                     90:                        KeyUp(code);
                     91:                }
                     92:        }
1.1.1.9   root       93: 
                     94:        timer.Stop();
                     95: 
1.1.1.13  root       96:        WXUIMessage::Disconnect(UIMessage::KEYBOARD, this,
1.1.1.8   root       97:                wxCommandEventHandler(WXSoftKeyPanel::OnKeyChanged));
1.1       root       98: }
                     99: 
1.1.1.11  root      100: // キーボードの接続状況によって親フレームのタイトルを更新する。
                    101: // ついでにメンバ変数を更新する。
                    102: void
                    103: WXSoftKeyPanel::UpdateTitle()
                    104: {
                    105:        auto parent = dynamic_cast<WXSoftKeyWindow *>(GetParent());
                    106:        assert(parent);
                    107: 
                    108:        // 次回比較用にメンバ変数に覚えておく
1.1.1.13  root      109:        connected = keyboard->IsConnected();
1.1.1.11  root      110: 
                    111:        if (connected) {
                    112:                parent->SetTitle(title);
                    113:        } else {
                    114:                parent->SetTitle(title + _(" (disconnected)"));
                    115:        }
                    116: }
                    117: 
1.1.1.9   root      118: // color.Keytop の初期化(補間)。
                    119: // num はキートップの種類の数。1 か 2
                    120: void
                    121: WXSoftKeyPanel::InitColorKeytop(int num)
                    122: {
1.1.1.11  root      123:        Color pressed = UD_BLUE;
1.1.1.9   root      124: 
                    125:        auto f = [](int a, int b, int x) {
                    126:                return a * x / 100 + b * (100 - x) / 100;
                    127:        };
                    128: 
                    129:        // Keytop[i][9] は押されたときの色
                    130:        // Keytop[i][0] は押されていないときの色
                    131:        for (int i = 0; i < num; i++) {
                    132:                for (int j = 1; j < 10; j++) {
                    133:                        int n = j * 100 / 9;
1.1.1.11  root      134:                        color.Keytop[i][j] = Color(
                    135:                                f(pressed.r, color.Keytop[i][0].r, n),
                    136:                                f(pressed.g, color.Keytop[i][0].g, n),
                    137:                                f(pressed.b, color.Keytop[i][0].b, n));
1.1.1.9   root      138:                }
                    139:        }
                    140: }
                    141: 
1.1.1.11  root      142: // フォントサイズ変更
1.1       root      143: void
1.1.1.11  root      144: WXSoftKeyPanel::FontChanged()
1.1       root      145: {
1.1.1.11  root      146:        inherited::FontChanged();
1.1       root      147: 
                    148:        // このパネル内の描画の基本単位
                    149:        unit = font_height / 4;
                    150: 
                    151:        // エンターキーだけ矩形でないのでここでリージョンを計算。
                    152:        // unit が確定したところで一回行う。
1.1.1.6   root      153:        // ただし SHIFT_R のキーコードはちょっと使いづらいので、ここでは SHIFT_R
                    154:        // を使わず [_] キーで代用する。
                    155:        //
                    156:        //   |   ^   |   \   |   BS  |
                    157:        //   |       |       |       |
                    158:        // --+---+---+--(A)--+------(B)
                    159:        //       |       |           |
1.1.1.11  root      160:        //       |   [   |   Enter   |
                    161:        //       |       |           |
                    162:        // --+---+---+--(F)-(E) - - (G)
1.1.1.6   root      163:        //   |       |       |       |
                    164:        //   |   :   |   ]   |       |
                    165:        //   |       |       |       |
                    166:        // --+---+---+------(D)-----(C)
                    167:        //       |                   |
                    168:        //   _   |      SHIFT        |
1.1       root      169:        //
1.1.1.11  root      170:        // Enter キーの上半分 A-B-G-F を enter_top。F-G の線分を含む。
                    171:        // Enter キーの下半分 E-G-C-D を enter_btm。E-G の線分を含む。
1.1       root      172:        const keydata_t& keybs = FindKeydata(KC_BS);
                    173:        const keydata_t& keyleft = FindKeydata(KC_bracketleft);
                    174:        const keydata_t& keyright = FindKeydata(KC_bracketright);
1.1.1.6   root      175:        const keydata_t& keyscore = FindKeydata(KC_underscore);
1.1.1.11  root      176:        enter_top.SetLTRB(
                    177:                keyleft.right() * unit, keyleft.y * unit,
                    178:                keybs.right() * unit, keyright.y * unit);
                    179:        enter_btm.SetLTRB(
                    180:                keyright.right() * unit, keyright.y * unit,
                    181:                keybs.right() * unit, keyscore.y * unit);
1.1       root      182: 
1.1.1.13  root      183:        // アイコンを変更。参照順序の関係で下のほうにおいてある…。
                    184:        InitIcon();
                    185: 
1.1.1.15  root      186:        // バックバッファの下限を固定する
1.1.1.4   root      187:        wxSize size(u_width * unit, u_height * unit);
1.1.1.15  root      188:        SetMinBitmapSize(size);
1.1.1.13  root      189: 
                    190:        // コントロールの大きさを変更
1.1.1.15  root      191:        SetSize(size);
                    192:        SetMinSize(size);
1.1       root      193: }
                    194: 
1.1.1.9   root      195: void
                    196: WXSoftKeyPanel::OnTimer(wxTimerEvent& event)
                    197: {
                    198:        Refresh();
                    199: }
                    200: 
1.1.1.8   root      201: // キー状態変更イベント (UIMessage)
1.1.1.9   root      202: //
                    203: // キー状態変更イベントは、キーの状態が変わるたびに都度通知される。
                    204: // ソフトウェアキーボード入力とパススルーモードの入力では、どのキーに変化
                    205: // (押下 or 開放)があったかの情報は付属しない。各キーの押下状態は全キーを
                    206: // 逐一調査することで判定する。人間時間で起きる事象なのでこの計算量は許容。
                    207: // Char 入力モードの場合は、イベントのパラメータ引数 (GetInt() で取得可) に
                    208: // 入力のあったキーの共通キーコードが入っている (複数のキーが同時に押される
                    209: // 場合はキーの回数分のイベントが飛んでくる)。Char 入力モードにはキー開放
                    210: // という概念はない。
1.1.1.6   root      211: void
1.1.1.8   root      212: WXSoftKeyPanel::OnKeyChanged(wxCommandEvent& event)
1.1.1.6   root      213: {
1.1.1.9   root      214:        // Char 入力モードでキーが押された場合は、共通キーコードが送られてくるので、
                    215:        // persistence[] をここでセットする。
                    216:        // Char 入力モードでは、キーの Make/Break が一瞬で終わるため、このイベント
                    217:        // を受け取って Refresh() を発行 -> OnPaint() -> Draw() 内で IsPressed()
                    218:        // を調べた頃にはタイミング問題でもうキーが離されている可能性があるので、
                    219:        // 描画時に全キーを調べる方法は使えない。
                    220:        uint keycode = event.GetInt();
                    221:        if (keycode != 0) {
                    222:                assert(keycode < persistence.size());
                    223:                // 9 が減光時の初期値 (10 は減光しない点灯)
                    224:                persistence[keycode] = 9;
1.1.1.6   root      225:        }
1.1.1.9   root      226: 
1.1.1.10  root      227:        // トグルキーが開放されていたらトグル情報をクリアする。
                    228:        // ハードウェアキーボードを含む VM 側で開放された場合と、
                    229:        // ソフトウェアキーボードの KeyUp() で開放された場合のどちらも
                    230:        // ここでクリア。
                    231:        for (auto& k : toggle) {
1.1.1.13  root      232:                if (keyboard->IsPressed(k.first) == false) {
1.1.1.10  root      233:                        k.second = 0;
                    234:                }
                    235:        }
                    236: 
1.1.1.11  root      237:        // 接続状況が変わっていたらタイトルを更新。
1.1.1.13  root      238:        if (keyboard->IsConnected() != connected) {
1.1.1.11  root      239:                UpdateTitle();
                    240:        }
1.1.1.6   root      241: 
1.1.1.11  root      242:        Refresh();
1.1       root      243: }
                    244: 
                    245: // 描画本体
                    246: void
1.1.1.11  root      247: WXSoftKeyPanel::Draw()
1.1       root      248: {
1.1.1.9   root      249:        bool timer_start = false;
                    250: 
                    251:        // キー刻印の表示更新用に修飾キーの状態を更新。
                    252:        // 本来は IsShift() だけで判定すべきだが、Char 入力モードでいずれかの
                    253:        // SHIFT キーが減光中は SHIFT 刻印を継続してみるのはどうか。
                    254:        // 0 まで待つとうちの環境だと消灯した少し後に刻印が戻るように見えるため、
                    255:        // ある程度暗くなったところでもう切り替えてみる。閾値は適当。
                    256:        if ((2 < persistence[KC_SHIFT_L] && persistence[KC_SHIFT_L] < 10) ||
                    257:            (2 < persistence[KC_SHIFT_R] && persistence[KC_SHIFT_R] < 10) ||
                    258:                (2 < persistence[KC_SHIFT]   && persistence[KC_SHIFT]   < 10) ||
1.1.1.13  root      259:                keyboard->IsShift())
1.1.1.9   root      260:        {
                    261:                modifier = ModShift;
                    262:        } else {
                    263:                modifier = ModNormal;
                    264:        }
                    265: 
1.1.1.11  root      266:        auto text_color = color.Text;
                    267: 
                    268:        // キーボードが接続されていないときは刻印をグレーにしておく
1.1.1.13  root      269:        if (keyboard->IsConnected() == false) {
1.1.1.11  root      270:                text_color = UD_GREY;
                    271:        }
                    272:        SetTextForeColor(text_color);
1.1       root      273: 
1.1.1.6   root      274:        for (const auto& key : keydata) {
1.1.1.9   root      275:                int c = persistence[key.keycode];
                    276:                if (0 < c && c < 10) {
                    277:                        // Char 入力モードで減光中
                    278:                        c--;
                    279:                        timer_start = true;
1.1       root      280:                } else {
1.1.1.9   root      281:                        // そうでない場合に限り、現在の状態を問い合わせる
1.1.1.13  root      282:                        bool is_pressed = keyboard->IsPressed(key.keycode);
1.1.1.9   root      283:                        if (is_pressed) {
                    284:                                // 押されている
                    285:                                c = 10;
                    286:                        } else {
                    287:                                // 押されていない
                    288:                                c = 0;
                    289:                        }
                    290:                }
                    291:                // persistence[] は 10 が(減光しない)点灯、9..1 が減光中を示す。
                    292:                persistence[key.keycode] = c;
                    293:                // ただし色配列は 0..9 で 9 が最大点灯色
                    294:                if (c > 9) {
                    295:                        c = 9;
1.1       root      296:                }
                    297: 
1.1.1.9   root      298:                SetTextBackColor(color.Keytop[key.coltype][c]);
                    299: 
1.1.1.13  root      300:                // エンターキーとブザー表示は描き方が違うので別処理
                    301:                if (__predict_false(key.keycode == KC_enter)) {
1.1.1.11  root      302:                        DrawEnterKey();
1.1.1.13  root      303:                } else if (__predict_false(key.keycode == KC_buzzer)) {
                    304:                        DrawBuzzer(key);
1.1       root      305:                } else {
1.1.1.11  root      306:                        DrawKey(key);
1.1       root      307:                }
                    308:        }
                    309: 
1.1.1.9   root      310:        if (timer_start) {
                    311:                timer.Start(25);
                    312:        } else {
                    313:                timer.Stop();
                    314:        }
1.1       root      315: }
                    316: 
                    317: // 指定のキーを一つ (枠から刻印まで) 描画する。
1.1.1.16  root      318: // palette[FG] はテキスト色 (キーボード非接続ならグレー)。
                    319: // palette[BG] はこのキーの背景色 (押されているか、減光中か、
                    320: // 押されていない時の二色あるかも知れないキートップ色)。
1.1       root      321: void
1.1.1.11  root      322: WXSoftKeyPanel::DrawKey(const keydata_t& key)
1.1       root      323: {
1.1.1.10  root      324:        uint attr = TA::Normal;
                    325: 
1.1       root      326:        // 枠
1.1.1.16  root      327:        DrawKeyBox(key, palette[0], color.Text);
1.1       root      328: 
                    329:        // 刻印を選択
                    330:        const char *disp = key.disp[modifier];
                    331:        if (disp == NULL) {
                    332:                disp = key.disp[0];
                    333:        }
                    334: 
1.1.1.10  root      335:        // トグルキーのワンショット押しは太字で表示を区別したい
                    336:        const auto it = toggle.find(key.keycode);
                    337:        if (it != toggle.end()) {
                    338:                if (it->second) {
                    339:                        attr = TA::Em;
                    340:                }
                    341:        }
                    342: 
1.1       root      343:        // Shift_JIS に変換
                    344:        wxString utfstr(disp, wxConvUTF8);
1.1.1.11  root      345:        // mb_str() をキャストせずに一度保持しておく必要がある (scan-build 対策)
                    346:        auto mbstr = utfstr.mb_str(conv);
                    347:        const char *sjis = (const char *)mbstr;
1.1.1.4   root      348:        // 改行があれば2行に分割
                    349:        char sjis1[8] {};
                    350:        char sjis2[8] {};
                    351:        int sjislen;
                    352:        int row;
                    353:        const char *lf = strchr(sjis, '\n');
                    354:        if (lf == NULL) {
                    355:                // 1行なら、Shift_JIS での文字数は半角換算の文字数と一致する。
                    356:                sjislen = strlen(sjis);
                    357:                row = 1;
                    358:        } else {
                    359:                // 2行に分割。センタリングは1行目の長さだけで調べる。
                    360:                strncpy(sjis1, sjis, lf - sjis);
1.1.1.14  root      361:                strlcpy(sjis2, lf + 1, sizeof(sjis2));
1.1.1.4   root      362:                sjislen = strlen(sjis1);
                    363:                row = 2;
                    364:        }
1.1       root      365: 
1.1.1.16  root      366:        // X 方向のセンタリング。
                    367:        // unit 単位の計算では精度が足りないのでドット単位で計算する。
                    368:        int x = key.x * unit + (key.w - sjislen * 2) * unit / 2 + 1;
1.1       root      369: 
1.1.1.16  root      370:        // Y 方向のセンタリングは、端数が出ないのと LED 用オフセットが
                    371:        // unit 単位なので、unit 単位のまま計算して、後でドット単位にする。
                    372:        int y = key.y + (key.h - row * 4) / 2;
1.1.1.4   root      373:        // LED を描画 (機種によって色々違うので個別クラス側で処理)
                    374:        if (key.led >= 0) {
1.1.1.11  root      375:                y += DrawLED(key);
1.1       root      376:        }
1.1.1.16  root      377:        y = y * unit + 1;
1.1       root      378: 
                    379:        // 文字を描画
1.1.1.4   root      380:        if (strcmp(disp, EnterMark) == 0) {
1.1.1.14  root      381:                bitmap.DrawBitmapI1(x, y, *enter_icon, palette);
1.1       root      382:        } else {
1.1.1.4   root      383:                if (lf == NULL) {
                    384:                        // 1行の場合
1.1.1.11  root      385:                        DrawStringSJIS(x, y, sjis, attr);
1.1.1.4   root      386:                } else {
                    387:                        // 2行の場合
1.1.1.11  root      388:                        DrawStringSJIS(x, y, sjis1);
                    389:                        y += 4 * unit;
                    390:                        DrawStringSJIS(x, y, sjis2);
1.1.1.4   root      391:                }
1.1       root      392:        }
                    393: }
                    394: 
1.1.1.16  root      395: // キーの枠と背景色を描画する。
                    396: void
                    397: WXSoftKeyPanel::DrawKeyBox(const keydata_t& key, Color bg, Color bd)
                    398: {
                    399:        Rect rect(
                    400:                key.x * unit,     key.y * unit,
                    401:                key.w * unit + 1, key.h * unit + 1);
                    402:        bitmap.FillRect(bg, rect);
                    403:        bitmap.DrawRect(bd, rect);
                    404: }
                    405: 
1.1       root      406: // エンターキー
                    407: void
1.1.1.11  root      408: WXSoftKeyPanel::DrawEnterKey()
1.1       root      409: {
1.1.1.11  root      410:        // 矩形の内側を背景色で塗りつぶす。
                    411:        bitmap.FillRect(palette[0], enter_top);
                    412:        bitmap.FillRect(palette[0], enter_btm);
                    413: 
                    414:        // 周囲の線分
                    415:        // (A)-(B)
                    416:        bitmap.DrawLineH(color.Text,
                    417:                enter_top.x, enter_top.y, enter_top.GetRight());
                    418:        // (B)-(C)
                    419:        bitmap.DrawLineV(color.Text,
                    420:                enter_top.GetRight(), enter_top.y, enter_btm.GetBottom());
                    421:        // (C)-(D)
                    422:        bitmap.DrawLineH(color.Text,
                    423:                enter_btm.GetRight(), enter_btm.GetBottom(), enter_btm.x);
                    424:        // (D)-(E)
                    425:        bitmap.DrawLineV(color.Text,
                    426:                enter_btm.x, enter_btm.GetBottom(), enter_btm.y);
                    427:        // (E)-(F)
                    428:        bitmap.DrawLineH(color.Text,
                    429:                enter_btm.x, enter_top.GetBottom(), enter_top.x);
                    430:        // (F)-(A)
                    431:        bitmap.DrawLineV(color.Text,
                    432:                enter_top.x, enter_top.GetBottom(), enter_top.y);
1.1       root      433: 
                    434:        // エンター記号を描画
1.1.1.14  root      435:        bitmap.DrawBitmapI1(
1.1.1.11  root      436:                (enter_top.x + enter_top.GetRight())  / 2 - (4 / 2),
1.1.1.13  root      437:                (enter_top.y + enter_btm.GetBottom()) / 2 - (4 / 2),
                    438:                *enter_icon, palette);
1.1.1.11  root      439: }
                    440: 
1.1.1.13  root      441: // ブザー表示(キーに相当)を描画
                    442: void
                    443: WXSoftKeyPanel::DrawBuzzer(const keydata_t& key)
                    444: {
                    445:        Color fg;
                    446: 
                    447:        // 枠。キーではないので薄くしておく。
1.1.1.16  root      448:        DrawKeyBox(key, palette[0], UD_GREY);
1.1.1.13  root      449: 
                    450:        // テキスト色は本来呼び出し元の DrawKey() で設定してあるが、
                    451:        // ここはキーではないので非発声時の文字色だけ薄くしたい。
                    452:        // 発声時はキー押下と同じにする。
                    453:        fg = GetTextForeColor();
                    454:        if (persistence[key.keycode] == 0) {
                    455:                SetTextForeColor(UD_GREY);
                    456:        }
1.1.1.11  root      457: 
1.1.1.13  root      458:        // 刻印 (モディファイヤの影響を受けないと分かっているので常に [0])
                    459:        const char *disp = key.disp[0];
                    460:        assert(disp);
                    461: 
                    462:        // センタリング
                    463:        int x = key.x + (key.w - strlen(disp) * 2) / 2;
                    464:        int y = key.y + (key.h - 4) / 2;
                    465: 
                    466:        // 文字を描画
                    467:        x = x * unit + 1;
                    468:        y = y * unit + 1;
                    469:        DrawStringSJIS(x, y, disp, TA::Normal);
                    470: 
                    471:        // 前景色を元に戻す
                    472:        SetTextForeColor(fg);
                    473: }
                    474: 
                    475: #define B(x)   (0b##x)
                    476: #define B2(x)  (B(x) >> 8), (B(x) & 0xff)
                    477: #define B3(x)  (B(x) >> 16), ((B(x) >> 8) & 0xff), (B(x) & 0xff)
                    478: 
                    479: static const uint8 EnterIcon12[] = {   // 12x12
                    480:        B2(000000000000'0000),  // 0
                    481:        B2(000000001110'0000),  // 1
                    482:        B2(000000001010'0000),  // 2
                    483:        B2(000000001010'0000),  // 3
                    484:        B2(000000001010'0000),  // 4
                    485:        B2(001100001010'0000),  // 5
                    486:        B2(010111110010'0000),  // 6
                    487:        B2(100000000010'0000),  // 7
                    488:        B2(010111111100'0000),  // 8
                    489:        B2(001100000000'0000),  // 9
                    490:        B2(000000000000'0000),  // a
                    491:        B2(000000000000'0000),  // b
1.1.1.11  root      492: };
1.1.1.13  root      493: 
                    494: static const uint8 EnterIcon16[] = {   // 16x16
                    495:        B2(0000000000111110),   // 0
                    496:        B2(0000000000100010),   // 1
                    497:        B2(0000000000100010),   // 2
                    498:        B2(0000000000100010),   // 3
                    499:        B2(0000000000100010),   // 4
                    500:        B2(0000000000100010),   // 5
                    501:        B2(0000000000100010),   // 6
                    502:        B2(0000110000100010),   // 7
                    503:        B2(0001010000100010),   // 8
                    504:        B2(0010011111000010),   // 9
                    505:        B2(0100000000000010),   // a
                    506:        B2(1000000000000010),   // b
                    507:        B2(0100000000000010),   // c
                    508:        B2(0010011111111100),   // d
                    509:        B2(0001010000000000),   // e
                    510:        B2(0000110000000000),   // f
1.1.1.11  root      511: };
1.1       root      512: 
1.1.1.13  root      513: static const uint8 EnterIcon24[] = {   // 24x24
                    514:        B3(00000000'00000001'11111100), // 0
                    515:        B3(00000000'00000001'11111100), // 1
                    516:        B3(00000000'00000001'10001100), // 2
                    517:        B3(00000000'00000001'10001100), // 3
                    518:        B3(00000000'00000001'10001100), // 4
                    519:        B3(00000000'00000001'10001100), // 5
                    520:        B3(00000000'00000001'10001100), // 6
                    521:        B3(00000000'00000001'10001100), // 7
                    522:        B3(00000000'00000001'10001100), // 8
                    523:        B3(00000000'11000001'10001100), // 9
                    524:        B3(00000001'11000001'10001100), // 10
                    525:        B3(00000011'11000001'10001100), // 11
                    526:        B3(00000110'11000001'10001100), // 12
                    527:        B3(00001100'11111111'10001100), // 13
                    528:        B3(00011000'11111111'10001100), // 14
                    529:        B3(00110000'00000000'00001100), // 15
                    530:        B3(01100000'00000000'00001100), // 16
                    531:        B3(00110000'00000000'00001100), // 17
                    532:        B3(00011000'11111111'11111100), // 18
                    533:        B3(00001100'11111111'11111000), // 19
                    534:        B3(00000110'11000000'00000000), // 20
                    535:        B3(00000011'11000000'00000000), // 21
                    536:        B3(00000001'11000000'00000000), // 22
                    537:        B3(00000000'11000000'00000000), // 23
                    538: };
                    539: 
                    540: // アイコンを初期化する。FontChanged() から呼ばれる。
                    541: // ソース先頭のほうにデータの羅列を置きたくないが、
                    542: // 容量不詳の配列の解決が面倒なのでこれだけ下のほうのここに置いてある。
1.1       root      543: void
1.1.1.13  root      544: WXSoftKeyPanel::InitIcon()
1.1       root      545: {
1.1.1.13  root      546:        const int width  = font_width;
                    547:        const int height = font_height;
                    548:        const uint8 *icon;
1.1.1.11  root      549: 
1.1.1.13  root      550:        switch (height) {
1.1.1.11  root      551:         case 12:
1.1.1.13  root      552:                icon = EnterIcon12;
1.1.1.11  root      553:                break;
                    554:         case 16:
1.1.1.13  root      555:                icon = EnterIcon16;
                    556:                break;
                    557:         case 24:
                    558:                icon = EnterIcon24;
1.1.1.11  root      559:                break;
                    560:         default:
1.1.1.13  root      561:                PANIC("Unexpected font_height=%d", height);
1.1       root      562:        }
1.1.1.13  root      563: 
                    564:        enter_icon.reset(new BitmapI1(icon, width * 2, height));
1.1       root      565: }
                    566: 
                    567: // keycode に対応する keydata を返す
                    568: const keydata_t&
1.1.1.4   root      569: WXSoftKeyPanel::FindKeydata(uint keycode) const
1.1       root      570: {
1.1.1.6   root      571:        for (const auto& key : keydata) {
1.1       root      572:                if (key.keycode == keycode) {
                    573:                        return key;
                    574:                }
                    575:        }
                    576:        // 見付からないはずはない
1.1.1.11  root      577:        PANIC("keycode %d not found", keycode);
1.1       root      578: }
                    579: 
                    580: // マウス左クリック (Down) イベント
                    581: void
1.1.1.4   root      582: WXSoftKeyPanel::OnLeftDown(wxMouseEvent& event)
1.1       root      583: {
1.1.1.5   root      584:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      585:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      586: 
1.1.1.9   root      587:        if (key != NULL) {
1.1.1.10  root      588:                DoLeftDown(key->keycode);
1.1.1.9   root      589:        }
1.1       root      590: }
                    591: 
                    592: // マウス左クリック (Down) 処理
                    593: void
1.1.1.10  root      594: WXSoftKeyPanel::DoLeftDown(uint code)
1.1       root      595: {
1.1.1.10  root      596:        auto it = toggle.find(code);
                    597:        if (it != toggle.end()) {
                    598:                // トグルキーはここで完結。LeftUp では何もしない。
                    599:                // second のクリアは KeyUp() からコールバックされる OnKeyChanged()
                    600:                // で行っている。
1.1.1.13  root      601:                if (keyboard->IsPressed(code)) {
1.1.1.10  root      602:                        KeyUp(code);
1.1.1.9   root      603:                } else {
1.1.1.10  root      604:                        KeyDown(code);
                    605:                        it->second = code;
1.1.1.9   root      606:                }
1.1.1.10  root      607:                leftdown_key = KC_none;
1.1.1.9   root      608:        } else {
1.1.1.10  root      609:                // トグルでない通常キーはここで押下して LeftUp のために覚えておく
                    610:                KeyDown(code);
                    611:                leftdown_key = code;
1.1       root      612:        }
                    613: }
                    614: 
                    615: // マウス左クリック (Up) イベント
                    616: void
1.1.1.4   root      617: WXSoftKeyPanel::OnLeftUp(wxMouseEvent& event)
1.1       root      618: {
                    619:        // Up 時は、これが起きた地点のキーコードではなく
                    620:        // 直近に LeftDown したキーコードをターゲットにする。
1.1.1.10  root      621:        uint code = leftdown_key;
1.1       root      622: 
1.1.1.10  root      623:        if (code != KC_none) {
                    624:                KeyUp(code);
1.1.1.9   root      625: 
1.1.1.10  root      626:                // 通常キーが離されたら、トグルキーはすべて開放
                    627:                for (const auto& k : toggle) {
                    628:                        auto tcode = k.second;
                    629:                        if (tcode) {
                    630:                                KeyUp(tcode);
1.1.1.9   root      631:                        }
                    632:                }
1.1       root      633:        }
1.1.1.9   root      634: 
1.1.1.10  root      635:        leftdown_key = KC_none;
1.1       root      636: }
                    637: 
                    638: // マウス左ダブルクリックイベント
                    639: // ダブルクリックという操作に特別何かを割り当ててはいないが、
                    640: // キーを連打するとその間隔によってはダブルクリックと扱われるため、
                    641: // 受け取ってここで処理する。
                    642: //
                    643: // DClick イベントは LeftDown、LeftUp、LeftDClick、LeftUp の順で
                    644: // 飛んでくるので、ここでは2回目の押下だけ処理すればよい。というか
                    645: // 処理自体は LeftDown とまったく同じになるので、イベントテーブルで
                    646: // 直接 EVT_LEFT_DCLICK => OnLeftDown に割り付けることも出来そうだが
                    647: // デバッグが紛らわしくなりそうなので独立したイベントとしておく。
                    648: void
1.1.1.4   root      649: WXSoftKeyPanel::OnLeftDClick(wxMouseEvent& event)
1.1       root      650: {
1.1.1.5   root      651:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      652:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      653: 
1.1.1.9   root      654:        if (key != NULL) {
1.1.1.10  root      655:                DoLeftDown(key->keycode);
1.1.1.9   root      656:        }
1.1       root      657: }
                    658: 
                    659: // マウス右クリック (Down) イベント
                    660: // 長押し開始/解除。
                    661: // 右クリックのほうは Down だけで Up は使わない。
                    662: void
1.1.1.4   root      663: WXSoftKeyPanel::OnRightDown(wxMouseEvent& event)
1.1       root      664: {
1.1.1.5   root      665:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      666:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      667: 
1.1.1.4   root      668:        if (key != NULL) {
                    669:                uint code = key->keycode;
1.1.1.13  root      670:                if (keyboard->IsPressed(code)) {
1.1       root      671:                        // 押されていたら開放
1.1.1.10  root      672:                        KeyUp(code);
1.1       root      673:                } else {
                    674:                        // 押されてなければ長押し開始
1.1.1.10  root      675:                        KeyDown(code);
1.1       root      676:                }
                    677:        }
                    678: }
                    679: 
1.1.1.4   root      680: // 座標からキーデータを返す。
                    681: // キーに当たっていなければ NULL を返す。
                    682: const keydata_t *
                    683: WXSoftKeyPanel::GetKeydataFromPoint(const wxPoint& pt) const
1.1       root      684: {
1.1.1.4   root      685:        // エンターキーだけ先に別判定
1.1.1.11  root      686:        if (enter_top.Contains(pt.x, pt.y) || enter_btm.Contains(pt.x, pt.y)) {
1.1.1.4   root      687:                return &FindKeydata(KC_enter);
                    688:        }
1.1       root      689: 
1.1.1.6   root      690:        for (const auto& key : keydata) {
1.1.1.4   root      691:                if (key.x < 0) {
                    692:                        continue;
1.1       root      693:                }
1.1.1.4   root      694:                // 始点と幅の +1/-1 は罫線の分
                    695:                wxRect rect(
                    696:                        (key.x * unit) + 1,
                    697:                        (key.y * unit) + 1,
                    698:                        (key.w * unit) - 1,
                    699:                        (key.h * unit) - 1);
                    700:                if (rect.Contains(pt)) {
                    701:                        return &key;
1.1       root      702:                }
1.1.1.4   root      703:        }
                    704:        return NULL;
                    705: }
                    706: 
1.1.1.6   root      707: // このキーが押された処理
                    708: void
1.1.1.10  root      709: WXSoftKeyPanel::KeyDown(uint code)
1.1.1.6   root      710: {
1.1.1.9   root      711:        // VM に通知 (Keyboard がホストに通知する)
1.1.1.13  root      712:        keyboard->MakeKey(code);
1.1.1.6   root      713: }
                    714: 
                    715: // このキーが放された処理
                    716: void
1.1.1.10  root      717: WXSoftKeyPanel::KeyUp(uint code)
1.1.1.6   root      718: {
1.1.1.9   root      719:        // VM に通知 (Keyboard がホストに通知する)
1.1.1.13  root      720:        keyboard->BreakKey(code);
1.1.1.6   root      721: }
                    722: 
1.1.1.16  root      723: // LUNA-I、LUNA-88K のコンストラクタ共通部分。
                    724: // クラス階層を増やすのも手間なので。
                    725: void
                    726: WXSoftKeyPanel::InitLunaCommon()
1.1.1.4   root      727: {
                    728:        // LUNA では
                    729:        // BS キーの左隣 (0x5c) は円記号ではなくバックスラッシュ。
                    730:        // それを SHIFT したやつ(0x7c) は破線でないパイプ。
                    731:        // そのもう一つ左隣 (0x7e) はオーバーラインではなくチルダ。
1.1.1.11  root      732:        gFontManager->SetGlyph5C(true);
                    733:        gFontManager->SetGlyph7E(true);
1.1.1.4   root      734: 
1.1.1.9   root      735:        // 白黒モデル共通
1.1.1.11  root      736:        color.Border = UD_BLACK;
1.1.1.9   root      737:        color.LED[0] = UD_RED;
                    738: 
1.1.1.4   root      739:        // キートップの濃淡はユニバーサルデザインの推奨色ではないけど
                    740:        // ここは見分けを付けるためではなくただのデザインなので。
                    741:        if (1) {
                    742:                // 白モデル
1.1.1.9   root      743:                color.Background        = UD_LIGHT_GREY;        // 現物新品は何色だったんだろう
1.1.1.11  root      744:                color.Text                      = UD_BLACK;
                    745:                color.Keytop[0][0]      = UD_WHITE;
                    746:                color.Keytop[1][0]      = Color(200, 200, 203);
1.1.1.4   root      747:        } else {
                    748:                // 黒モデル
1.1.1.11  root      749:                color.Background        = UD_BLACK;
                    750:                color.Text                      = UD_WHITE;
                    751:                color.Keytop[0][0]      = Color(50, 50, 53);
                    752:                color.Keytop[1][0]      = UD_BLACK;
1.1.1.4   root      753:        }
1.1.1.9   root      754:        InitColorKeytop(2);
1.1.1.11  root      755: 
                    756:        SetBitmapBGColor(color.Background);
1.1.1.13  root      757:        Fill();
1.1.1.4   root      758: }
                    759: 
1.1.1.16  root      760: 
                    761: //
                    762: // LUNA-I ソフトウェアキーボード (パネル)
                    763: //
                    764: 
                    765: // コンストラクタ
                    766: WXLuna1SoftKeyPanel::WXLuna1SoftKeyPanel(wxWindow *parent)
                    767:        : inherited(parent, keydata, 226, 54)
                    768: {
                    769:        InitLunaCommon();
                    770: }
                    771: 
1.1.1.4   root      772: // デストラクタ
1.1.1.16  root      773: WXLuna1SoftKeyPanel::~WXLuna1SoftKeyPanel()
1.1.1.4   root      774: {
                    775: }
                    776: 
                    777: // LED を描画して刻印描画のための y offset を返す。
                    778: int
1.1.1.16  root      779: WXLuna1SoftKeyPanel::DrawLED(const keydata_t& key)
1.1.1.4   root      780: {
1.1.1.13  root      781:        const std::vector<bool>& led = keyboard->GetLED();
1.1.1.11  root      782:        Color fg;
                    783:        Color bg;
1.1.1.4   root      784: 
                    785:        if (led[key.led]) {
                    786:                // 点灯時は赤、枠は黒
1.1.1.11  root      787:                fg = color.Border;
                    788:                bg = color.LED[0];
1.1       root      789:        } else {
1.1.1.4   root      790:                // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6   root      791:                // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
1.1.1.11  root      792:                fg = UD_GREY;
                    793:                bg = color.Keytop[key.coltype][0];
1.1       root      794:        }
                    795: 
1.1.1.4   root      796:        // LED を左肩に描く
1.1.1.11  root      797:        Rect rect(key.x * unit + 2, key.y * unit + 2, 4 * unit - 2, 3 * unit - 2);
                    798:        bitmap.FillRect(bg, rect);
                    799:        bitmap.DrawRect(fg, rect);
1.1.1.4   root      800: 
                    801:        // そのため文字は少し下げる
                    802:        return +1;
                    803: }
                    804: 
1.1.1.16  root      805: // LUNA-I のファンクションキーは ESC 行との間が少し空いている。
                    806: // LUNA-88K のファンクションキー行は ESC 行とぴったりついていて、キーの
                    807: // 縦の長さも他のキーと同じ感じ。
                    808: // X68030 のファンクションキーは ESC 行との間が空いていて、キーの長さは
                    809: // 他より短い。
                    810: //
                    811: //  2 - +--------+
                    812: //  4 - | LUNA-I | +-------+ +--------+
                    813: //  6 - |        | | 88K   | | X68030 |
                    814: //  8 - |        | |       | |        |
                    815: // 10 - +--------+ |       | +--------+
                    816: // 12 - +--------+ +-------+ +--------+  <- ESC 行の上辺
                    817: // 14 - |  ESC   | |   1   | |   2    |
                    818: //
1.1       root      819: #define H       (8)    // キーの高さ
1.1.1.16  root      820: #define LH      (2)    // ファンクションキーの行 (ESC 行との間に空き)
                    821: #define L0      (4)    // ファンクションキーは少し低い(横長い)
1.1       root      822: #define L1     (12)    // ESC の行
                    823: #define L2     (20)    // TAB の行
                    824: #define L3     (28)    // CTRL の行
                    825: #define L4     (36)    // SHIFT の行
                    826: #define L5     (44)    // space の行
1.1.1.16  root      827: 
                    828: // キーデータ
1.1       root      829: /*static*/ std::vector<keydata_t>
1.1.1.16  root      830: WXLuna1SoftKeyPanel::keydata {
1.1.1.4   root      831:        //                +---- キートップの色(1:濃)
                    832:        //                |  +- 0 以上なら LED 番号
                    833:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
1.1.1.16  root      834:        {   2, LH, 15, H, 1,-1, KC_F1,                          { "PF1" } },
                    835:        {  17, LH, 15, H, 1,-1, KC_F2,                          { "PF2" } },
                    836:        {  32, LH, 15, H, 1,-1, KC_F3,                          { "PF3" } },
                    837:        {  47, LH, 15, H, 1,-1, KC_F4,                          { "PF4" } },
                    838:        {  62, LH, 15, H, 1,-1, KC_F5,                          { "PF5" } },
                    839:        {  81, LH, 15, H, 1,-1, KC_F6,                          { "PF6" } },
                    840:        {  96, LH, 15, H, 1,-1, KC_F7,                          { "PF7" } },
                    841:        { 111, LH, 15, H, 1,-1, KC_F8,                          { "PF8" } },
                    842:        { 126, LH, 15, H, 1,-1, KC_F9,                          { "PF9" } },
                    843:        { 141, LH, 15, H, 1,-1, KC_F10,                         { "PF10" } },
                    844:        { 210, LH+1, 14, H-2, 1,-1, KC_buzzer,          { "Buzzer" } },
1.1.1.4   root      845: 
                    846:        {   2, L1, 12, H, 1,-1, KC_ESC,                         { "ESC" } },
                    847:        {  14, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
                    848:        {  24, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
                    849:        {  34, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
                    850:        {  44, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
                    851:        {  54, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
                    852:        {  64, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
                    853:        {  74, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
                    854:        {  84, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
                    855:        {  94, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
                    856:        { 104, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
                    857:        { 114, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
                    858:        { 124, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
                    859:        { 134, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
                    860:        { 144, L1, 12, H, 1,-1, KC_BS,                          { "BS" } },
                    861: 
                    862:        {   2, L2, 17, H, 1,-1, KC_TAB,                         { "TAB" } },
                    863:        {  19, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
                    864:        {  29, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
                    865:        {  39, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
                    866:        {  49, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
                    867:        {  59, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
                    868:        {  69, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
                    869:        {  79, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
                    870:        {  89, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
                    871:        {  99, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
                    872:        { 109, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
                    873:        { 119, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
                    874:        { 129, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
                    875: 
                    876:        {   2, L3, 20, H, 1,-1, KC_CTRL,                        { "CTRL" } },
                    877:        {  22, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
                    878:        {  32, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
                    879:        {  42, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
                    880:        {  52, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
                    881:        {  62, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
                    882:        {  72, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
                    883:        {  82, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
                    884:        {  92, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
                    885:        { 102, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
                    886:        { 112, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
                    887:        { 122, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
                    888:        { 132, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
                    889: 
                    890:        {   2, L4, 25, H, 1,-1, KC_SHIFT_L,                     { "SHIFT" } },
                    891:        {  27, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
                    892:        {  37, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
                    893:        {  47, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
                    894:        {  57, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
                    895:        {  67, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
                    896:        {  77, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
                    897:        {  87, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
                    898:        {  97, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
                    899:        { 107, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
                    900:        { 117, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
                    901:        { 127, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
                    902:        { 137, L4, 19, H, 1,-1, KC_SHIFT_R,                     { "SHIFT" } },
                    903: 
                    904:        {   2, L5, 20, H, 1,-1, KC_VALID,                       { "確定" } },
                    905:        {  22, L5, 10, H, 1,-1, KC_SF,                          { "前面" } },
                    906:        {  32, L5, 10, H, 1, 1, KC_CAPS,                        { "CAP" } },
                    907:        {  42, L5, 80, H, 0,-1, KC_space,                       { " " } },
                    908:        { 122, L5, 10, H, 1, 0, KC_kana,                        { "かな" } },
                    909:        { 132, L5, 24, H, 1,-1, KC_XFER,                        { "変換" } },
1.1       root      910: 
                    911:        // カーソルキー島
1.1.1.4   root      912:        { 160, L1, 10, H, 1,-1, KC_PF11,                        { "消去" } },
                    913:        { 170, L1, 10, H, 1,-1, KC_PF12,                        { "呼出" } },
                    914:        { 160, L2, 10, H, 1,-1, KC_PF13,                        { "文節\n←" } },
                    915:        { 170, L2, 10, H, 1,-1, KC_PF14,                        { "文節\n→" } },
                    916:        { 160, L3, 20, H, 1,-1, KC_up,                          { "↑" } },
                    917:        { 160, L4, 10, H, 1,-1, KC_left,                        { "←" } },
                    918:        { 170, L4, 10, H, 1,-1, KC_right,                       { "→" } },
                    919:        { 160, L5, 20, H, 1,-1, KC_down,                        { "↓" } },
1.1       root      920: 
                    921:        // テンキー島
1.1.1.4   root      922:        { 184, L1, 10, H, 1,-1, KC_DEL,                         { "DEL" } },
                    923:        { 194, L1, 10, H, 1,-1, KC_PAD_plus,            { "+" } },
                    924:        { 204, L1, 10, H, 1,-1, KC_PAD_minus,           { "-" } },
                    925:        { 214, L1, 10, H, 1,-1, KC_PAD_multiply,        { "*" } },
                    926: 
                    927:        { 184, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
                    928:        { 194, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
                    929:        { 204, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
                    930:        { 214, L2, 10, H, 1,-1, KC_PAD_divide,          { "/" } },
                    931: 
                    932:        { 184, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
                    933:        { 194, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
                    934:        { 204, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
                    935:        { 214, L3, 10, H, 1,-1, KC_PAD_equal,           { "=" } },
                    936: 
                    937:        { 184, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
                    938:        { 194, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
                    939:        { 204, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
                    940:        { 214, L4, 10, H, 1,-1, KC_PAD_comma,           { "," } },
                    941: 
                    942:        { 184, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
                    943:        { 194, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
                    944:        { 204, L5, 20, H, 1,-1, KC_PAD_enter,           { EnterMark } },
1.1       root      945: 
                    946:        // Enter だけ矩形でないので別処理するが
                    947:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
1.1.1.4   root      948:        { -1, -1, -1, -1, 1,-1, KC_enter,                       { EnterMark } },
1.1       root      949: };
                    950: 
                    951: 
                    952: //
1.1.1.16  root      953: // LUNA-88K ソフトウェアキーボード (パネル)
                    954: //
                    955: 
                    956: // コンストラクタ
                    957: WXLuna88kSoftKeyPanel::WXLuna88kSoftKeyPanel(wxWindow *parent)
                    958:        : inherited(parent, keydata, 226, 54)
                    959: {
                    960:        InitLunaCommon();
                    961: }
                    962: 
                    963: // デストラクタ
                    964: WXLuna88kSoftKeyPanel::~WXLuna88kSoftKeyPanel()
                    965: {
                    966: }
                    967: 
                    968: // LED を描画する。
                    969: // 独立 LED なので戻り値は使わないので 0 でいい。
                    970: int
                    971: WXLuna88kSoftKeyPanel::DrawLED(const keydata_t& basekey)
                    972: {
                    973:        const std::vector<bool>& led = keyboard->GetLED();
                    974:        Color fg_backup;
                    975:        Color bg_backup;
                    976:        Color fg;
                    977:        TA attr;
                    978: 
                    979:        fg_backup = GetTextForeColor();
                    980:        bg_backup = GetTextBackColor();
                    981: 
                    982:        if (led[basekey.led]) {
                    983:                // 点灯時、文字は LED 色でボールド。
                    984:                fg = color.LED[0];
                    985:                attr = TA::Bold;
                    986:        } else {
                    987:                // 消灯時、文字はグレーで通常体。
                    988:                fg = UD_GREY;
                    989:                attr = TA::Normal;
                    990:        }
                    991:        SetTextForeColor(fg);
                    992:        // 背景はキーの押し下げ状態ではなく常にキー開放色のままとする。
                    993:        SetTextBackColor(color.Keytop[1][0]);
                    994: 
                    995:        // LUNA-88K キーボードは LED 入りキーではなく、別のところに
                    996:        // LED だけがあるタイプ。(今どきの PC キーボードに近い)
                    997:        static const keydata_t led_caps = {
                    998:                184, L0+1, 10, H-2, 1, -1, 0, { "Caps" }
                    999:        };
                   1000:        static const keydata_t led_kana = {
                   1001:                194, L0+1, 10, H-2, 1, -1, 0, { "Kana" }
                   1002:        };
                   1003:        const keydata_t& key = (basekey.keycode == KC_CAPS)
                   1004:                ? led_caps
                   1005:                : led_kana;
                   1006: 
                   1007:        // 枠を描画。
                   1008:        // 2つの LED で枠が重なるため状態によって色を変えられない。
                   1009:        DrawKeyBox(key, color.Keytop[1][0], UD_GREY);
                   1010: 
                   1011:        // ラベルをセンタリング。
                   1012:        const char *disp = key.disp[0];
                   1013:        int x = key.x + (key.w - strlen(disp) * 2) / 2;
                   1014:        int y = key.y + (key.h - 4) / 2;
                   1015: 
                   1016:        // ラベルを描画。
                   1017:        x = x * unit + 1;
                   1018:        y = y * unit + 1;
                   1019:        DrawStringSJIS(x, y, disp, attr);
                   1020: 
                   1021:        // 前景色、背景色を元に戻す。
                   1022:        SetTextForeColor(fg_backup);
                   1023:        SetTextBackColor(bg_backup);
                   1024: 
                   1025:        // 元のキーの文字描画オフセットは無し。
                   1026:        return 0;
                   1027: }
                   1028: 
                   1029: 
                   1030: // キーデータ
                   1031: /*static*/ std::vector<keydata_t>
                   1032: WXLuna88kSoftKeyPanel::keydata {
                   1033:        //                +---- キートップの色(1:濃)
                   1034:        //                |  +- 0 以上なら LED 番号
                   1035:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
                   1036:        {   2, L0, 10, H, 1,-1, KC_F1,                          { "PF1" } },
                   1037:        {  12, L0, 10, H, 1,-1, KC_F2,                          { "PF2" } },
                   1038:        {  22, L0, 10, H, 1,-1, KC_F3,                          { "PF3" } },
                   1039:        {  32, L0, 10, H, 1,-1, KC_F4,                          { "PF4" } },
                   1040:        {  42, L0, 10, H, 1,-1, KC_F5,                          { "PF5" } },
                   1041:        {  52, L0, 10, H, 1,-1, KC_F6,                          { "PF6" } },
                   1042:        {  62, L0, 10, H, 1,-1, KC_F7,                          { "PF7" } },
                   1043:        {  72, L0, 10, H, 1,-1, KC_F8,                          { "PF8" } },
                   1044:        {  82, L0, 10, H, 1,-1, KC_F9,                          { "PF9" } },
                   1045:        {  92, L0, 10, H, 1,-1, KC_F10,                         { "PF10" } },
                   1046:        { 102, L0, 10, H, 1,-1, KC_PF11,                        { "消去" } },
                   1047:        { 112, L0, 10, H, 1,-1, KC_PF12,                        { "呼出" } },
                   1048:        { 122, L0, 10, H, 1,-1, KC_PF13,                        { "文節\n←" } },
                   1049:        { 132, L0, 10, H, 1,-1, KC_PF14,                        { "文節\n→" } },
                   1050:        { 142, L0, 14, H, 1,-1, KC_BS,                          { "BS" } },
                   1051: 
                   1052:        { 210, L0+1, 14, H-2, 1,-1, KC_buzzer,          { "Buzzer" } },
                   1053: 
                   1054:        {   2, L1, 12, H, 1,-1, KC_ESC,                         { "ESC" } },
                   1055:        {  14, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
                   1056:        {  24, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
                   1057:        {  34, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
                   1058:        {  44, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
                   1059:        {  54, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
                   1060:        {  64, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
                   1061:        {  74, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
                   1062:        {  84, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
                   1063:        {  94, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
                   1064:        { 104, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
                   1065:        { 114, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
                   1066:        { 124, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
                   1067:        { 134, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
                   1068:        { 144, L1, 12, H, 1,-1, KC_DEL,                         { "DEL" } },
                   1069: 
                   1070:        {   2, L2, 17, H, 1,-1, KC_TAB,                         { "TAB" } },
                   1071:        {  19, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
                   1072:        {  29, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
                   1073:        {  39, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
                   1074:        {  49, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
                   1075:        {  59, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
                   1076:        {  69, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
                   1077:        {  79, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
                   1078:        {  89, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
                   1079:        {  99, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
                   1080:        { 109, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
                   1081:        { 119, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
                   1082:        { 129, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
                   1083: 
                   1084:        {   2, L3, 20, H, 1,-1, KC_CTRL,                        { "CTRL" } },
                   1085:        {  22, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
                   1086:        {  32, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
                   1087:        {  42, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
                   1088:        {  52, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
                   1089:        {  62, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
                   1090:        {  72, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
                   1091:        {  82, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
                   1092:        {  92, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
                   1093:        { 102, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
                   1094:        { 112, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
                   1095:        { 122, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
                   1096:        { 132, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
                   1097: 
                   1098:        {   2, L4, 25, H, 1,-1, KC_SHIFT_L,                     { "SHIFT" } },
                   1099:        {  27, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
                   1100:        {  37, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
                   1101:        {  47, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
                   1102:        {  57, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
                   1103:        {  67, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
                   1104:        {  77, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
                   1105:        {  87, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
                   1106:        {  97, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
                   1107:        { 107, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
                   1108:        { 117, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
                   1109:        { 127, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
                   1110:        { 137, L4, 19, H, 1,-1, KC_SHIFT_R,                     { "SHIFT" } },
                   1111: 
                   1112:        {   2, L5, 10, H, 1,-1, KC_SF,                          { "META" } },
                   1113:        {  12, L5, 20, H, 1,-1, KC_VALID,                       { "確定" } },
                   1114:        {  32, L5, 10, H, 1, 1, KC_CAPS,                        { "CAPS" } },
                   1115:        {  42, L5, 80, H, 0,-1, KC_space,                       { " " } },
                   1116:        { 122, L5, 10, H, 1, 0, KC_kana,                        { "かな" } },
                   1117:        { 132, L5, 24, H, 1,-1, KC_XFER,                        { "変換" } },
                   1118: 
                   1119:        // カーソルキー島
                   1120:        { 159, L1, 11, H, 1,-1, KC_INS,                         { "INS" } },
                   1121:        { 170, L1, 11, H, 1,-1, KC_COPY,                        { "COPY" } },
                   1122:        { 159, L2, 11, H, 1,-1, KC_CUT,                         { "CUT" } },
                   1123:        { 170, L2, 11, H, 1,-1, KC_PASTE,                       { "PASTE" } },
                   1124:        { 159, L3, 22, H, 1,-1, KC_up,                          { "↑" } },
                   1125:        { 159, L4, 11, H, 1,-1, KC_left,                        { "←" } },
                   1126:        { 170, L4, 11, H, 1,-1, KC_right,                       { "→" } },
                   1127:        { 159, L5, 22, H, 1,-1, KC_down,                        { "↓" } },
                   1128: 
                   1129:        // テンキー島
                   1130:        { 184, L1, 10, H, 1,-1, KC_HOME,                        { "HOME" } },
                   1131:        { 194, L1, 10, H, 1,-1, KC_PAD_plus,            { "+" } },
                   1132:        { 204, L1, 10, H, 1,-1, KC_PAD_minus,           { "-" } },
                   1133:        { 214, L1, 10, H, 1,-1, KC_PAD_multiply,        { "*" } },
                   1134: 
                   1135:        { 184, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
                   1136:        { 194, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
                   1137:        { 204, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
                   1138:        { 214, L2, 10, H, 1,-1, KC_PAD_divide,          { "/" } },
                   1139: 
                   1140:        { 184, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
                   1141:        { 194, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
                   1142:        { 204, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
                   1143:        { 214, L3, 10, H, 1,-1, KC_PAD_equal,           { "=" } },
                   1144: 
                   1145:        { 184, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
                   1146:        { 194, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
                   1147:        { 204, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
                   1148:        { 214, L4, 10, H, 1,-1, KC_PAD_comma,           { "," } },
                   1149: 
                   1150:        { 184, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
                   1151:        { 194, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
                   1152:        { 204, L5, 20, H, 1,-1, KC_PAD_enter,           { EnterMark } },
                   1153: 
                   1154:        // Enter だけ矩形でないので別処理するが
                   1155:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
                   1156:        { -1, -1, -1, -1, 1,-1, KC_enter,                       { EnterMark } },
                   1157: };
                   1158: 
                   1159: 
                   1160: //
1.1.1.4   root     1161: // X68k ソフトウェアキーボード (パネル)
                   1162: //
                   1163: 
                   1164: // コンストラクタ
                   1165: WXX68kSoftKeyPanel::WXX68kSoftKeyPanel(wxWindow *parent)
1.1.1.6   root     1166:        : inherited(parent, keydata, 235, 54)
1.1.1.4   root     1167: {
                   1168:        // X68k では SRAM 設定に同期させる。
1.1.1.13  root     1169:        const auto sram = GetSRAMDevice();
1.1.1.14  root     1170:        uint8 sw = sram->Peek1(0xed0059);
1.1.1.11  root     1171:        gFontManager->SetGlyph5C((sw & 0x01));
                   1172:        gFontManager->SetGlyph7E((sw & 0x02));
                   1173:        gFontManager->SetGlyph7C((sw & 0x04));
1.1.1.4   root     1174: 
                   1175:        // とりあえず黒のみ
1.1.1.11  root     1176:        color.Background        = Color(50, 50, 53);
                   1177:        color.Text                      = UD_WHITE;
                   1178:        color.Border            = UD_BLACK;
1.1.1.9   root     1179:        color.LED[0]            = UD_RED;
                   1180:        color.LED[1]            = UD_YELLOW_GREEN;
1.1.1.11  root     1181:        color.Keytop[0][0]      = UD_BLACK;
1.1.1.9   root     1182:        InitColorKeytop(1);
1.1.1.11  root     1183: 
                   1184:        SetBitmapBGColor(color.Background);
1.1.1.13  root     1185:        Fill();
1.1.1.4   root     1186: }
                   1187: 
                   1188: // デストラクタ
                   1189: WXX68kSoftKeyPanel::~WXX68kSoftKeyPanel()
                   1190: {
                   1191: }
                   1192: 
                   1193: // LED を描画して刻印描画のための y offset を返す。
                   1194: int
1.1.1.11  root     1195: WXX68kSoftKeyPanel::DrawLED(const keydata_t& key)
1.1.1.4   root     1196: {
1.1.1.13  root     1197:        const std::vector<bool>& led = keyboard->GetLED();
1.1.1.11  root     1198:        Color fg;
                   1199:        Color bg;
1.1.1.4   root     1200: 
                   1201:        // 色を選択
                   1202:        // idx  刻印  色
                   1203:        // ----------------
                   1204:        //  0   かな  赤
                   1205:        //  1   ローマ       赤
                   1206:        //  2   コード       赤
                   1207:        //  3   CAPS    赤
                   1208:        //  4   INS             赤
                   1209:        //  5   ひら  緑
                   1210:        //  6   全角  緑
                   1211:        if (led[key.led]) {
                   1212:                int n = (key.led < 5) ? 0 : 1;
1.1.1.11  root     1213:                fg = color.LED[n];
                   1214:                bg = color.LED[n];
1.1.1.4   root     1215:        } else {
                   1216:                // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6   root     1217:                // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
1.1.1.11  root     1218:                fg = UD_GREY;
                   1219:                bg = color.Keytop[key.coltype][0];
1.1.1.4   root     1220:        }
                   1221: 
                   1222:        // LED は中央前方(画面でいうと下)
1.1.1.11  root     1223:        Rect rect((key.x + 3) * unit, (key.y + key.h - 2) * unit,
                   1224:                4 * unit, 2 * unit);
                   1225:        bitmap.FillRect(bg, rect);
                   1226:        bitmap.DrawRect(fg, rect);
1.1.1.4   root     1227: 
                   1228:        // そのため文字は少し上げる
                   1229:        return -1;
                   1230: }
                   1231: 
                   1232: #define HT (H * 2)             // 縦2倍角のキー
                   1233: /*static*/ std::vector<keydata_t>
                   1234: WXX68kSoftKeyPanel::keydata {
                   1235:        //                   +- 0以上なら LED 番号
                   1236:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
1.1.1.16  root     1237:        {   2, LH, 10, H, 0,-1, KC_BREAK,                       { "\x4\x5\x6\x7" } },
                   1238:        {  15, LH, 10, H, 0,-1, KC_COPY,                        { "COPY" } },
                   1239:        {  29, L0, 12, 6, 0,-1, KC_F1,                          { "F1" } },
                   1240:        {  41, L0, 12, 6, 0,-1, KC_F2,                          { "F2" } },
                   1241:        {  53, L0, 12, 6, 0,-1, KC_F3,                          { "F3" } },
                   1242:        {  65, L0, 12, 6, 0,-1, KC_F4,                          { "F4" } },
                   1243:        {  77, L0, 13, 6, 0,-1, KC_F5,                          { "F5" } },
                   1244:        {  94, L0, 13, 6, 0,-1, KC_F6,                          { "F6" } },
                   1245:        { 106, L0, 12, 6, 0,-1, KC_F7,                          { "F7" } },
                   1246:        { 118, L0, 12, 6, 0,-1, KC_F8,                          { "F8" } },
                   1247:        { 130, L0, 12, 6, 0,-1, KC_F9,                          { "F9" } },
                   1248:        { 142, L0, 13, 6, 0,-1, KC_F10,                         { "F10" } },
1.1.1.4   root     1249: 
                   1250:        {   2, L1, 10, H, 0,-1, KC_ESC,                         { "ESC" } },
                   1251:        {  12, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
                   1252:        {  22, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
                   1253:        {  32, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
                   1254:        {  42, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
                   1255:        {  52, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
                   1256:        {  62, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
                   1257:        {  72, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
                   1258:        {  82, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
                   1259:        {  92, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
                   1260:        { 102, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
                   1261:        { 112, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
                   1262:        { 122, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
                   1263:        { 132, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
                   1264:        { 142, L1, 13, H, 0,-1, KC_BS,                          { "BS" } },
                   1265: 
                   1266:        {   2, L2, 16, H, 0,-1, KC_TAB,                         { "TAB" } },
                   1267:        {  18, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
                   1268:        {  28, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
                   1269:        {  38, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
                   1270:        {  48, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
                   1271:        {  58, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
                   1272:        {  68, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
                   1273:        {  78, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
                   1274:        {  88, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
                   1275:        {  98, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
                   1276:        { 108, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
                   1277:        { 118, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
                   1278:        { 128, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
                   1279: 
                   1280:        {   2, L3, 19, H, 0,-1, KC_CTRL,                        { "CTRL" } },
                   1281:        {  21, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
                   1282:        {  31, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
                   1283:        {  41, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
                   1284:        {  51, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
                   1285:        {  61, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
                   1286:        {  71, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
                   1287:        {  81, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
                   1288:        {  91, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
                   1289:        { 101, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
                   1290:        { 111, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
                   1291:        { 121, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
                   1292:        { 131, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
                   1293: 
1.1.1.6   root     1294:        {   2, L4, 24, H, 0,-1, KC_SHIFT,                       { "SHIFT" } },
1.1.1.4   root     1295:        {  26, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
                   1296:        {  36, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
                   1297:        {  46, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
                   1298:        {  56, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
                   1299:        {  66, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
                   1300:        {  76, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
                   1301:        {  86, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
                   1302:        {  96, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
                   1303:        { 106, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
                   1304:        { 116, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
                   1305:        { 126, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
1.1.1.6   root     1306:        { 136, L4, 19, H, 0,-1, KC_SHIFT,                       { "SHIFT" } },
1.1.1.4   root     1307: 
                   1308:        {  21, L5, 10, H, 0, 5, KC_hira,                        { "ひら" } },
                   1309:        {  31, L5, 12, H, 0,-1, KC_XF1,                         { "XF1" } },
                   1310:        {  43, L5, 13, H, 0,-1, KC_XF2,                         { "XF2" } },
                   1311:        {  56, L5, 36, H, 0,-1, KC_space,                       { " " } },
                   1312:        {  92, L5, 12, H, 0,-1, KC_XF3,                         { "XF3" } },
                   1313:        { 104, L5, 12, H, 0,-1, KC_XF4,                         { "XF4" } },
                   1314:        { 116, L5, 12, H, 0,-1, KC_XF5,                         { "XF5" } },
                   1315:        { 128, L5, 10, H, 0, 6, KC_zenkaku,                     { "全角" } },
                   1316: 
                   1317:        // カーソルキー島
                   1318:        { 159, L0, 10, H, 0, 0, KC_kana,                        { "かな" } },
                   1319:        { 169, L0, 10, H, 0, 1, KC_romaji,                      { "ローマ" } },
                   1320:        { 179, L0, 10, H, 0, 2, KC_code,                        { "コード" } },
                   1321:        { 159, L1, 10, H, 0,-1, KC_HOME,                        { "HOME" } },
                   1322:        { 169, L1, 10, H, 0, 4, KC_INS,                         { "INS" } },
                   1323:        { 179, L1, 10, H, 0,-1, KC_DEL,                         { "DEL" } },
                   1324:        { 159, L2, 10, H, 0,-1, KC_ROLLUP,                      { "ROLL\n UP" } },
                   1325:        { 169, L2, 10, H, 0,-1, KC_ROLLDOWN,            { "ROLL\nDOWN" } },
                   1326:        { 179, L2, 10, H, 0,-1, KC_UNDO,                        { "UNDO" } },
                   1327:        { 169, L3, 10, H, 0,-1, KC_up,                          { "↑" } },
                   1328:        { 159, L3, 10, HT,0,-1, KC_left,                        { "←" } },
                   1329:        { 179, L3, 10, HT,0,-1, KC_right,                       { "→" } },
                   1330:        { 169, L4, 10, H, 0,-1, KC_down,                        { "↓" } },
                   1331:        { 159, L5, 15, H, 0,-1, KC_OPT1,                        { "OPT.1" } },
                   1332:        { 174, L5, 15, H, 0,-1, KC_OPT2,                        { "OPT.2" } },
                   1333: 
                   1334:        // テンキー島
                   1335:        { 193, L0, 10, H, 0, 3, KC_CAPS,                        { "CAPS" } },
                   1336:        { 203, L0, 10, H, 0,-1, KC_kigou,                       { "記号" } },
                   1337:        { 213, L0, 10, H, 0,-1, KC_touroku,                     { "登録" } },
                   1338:        { 223, L0, 10, H, 0,-1, KC_HELP,                        { "HELP" } },
                   1339:        { 193, L1, 10, H, 0,-1, KC_PAD_CLR,                     { "CLR" } },
                   1340:        { 203, L1, 10, H, 0,-1, KC_PAD_divide,          { "/" } },
                   1341:        { 213, L1, 10, H, 0,-1, KC_PAD_multiply,        { "*" } },
                   1342:        { 223, L1, 10, H, 0,-1, KC_PAD_minus,           { "-" } },
                   1343:        { 193, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
                   1344:        { 203, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
                   1345:        { 213, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
                   1346:        { 223, L2, 10, H, 0,-1, KC_PAD_plus,            { "+" } },
                   1347:        { 193, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
                   1348:        { 203, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
                   1349:        { 213, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
                   1350:        { 223, L3, 10, H, 0,-1, KC_PAD_equal,           { "=" } },
                   1351:        { 193, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
                   1352:        { 203, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
                   1353:        { 213, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
1.1.1.13  root     1354:        { 223, L4, 10, HT,0,-1, KC_PAD_enter,           { "\xb\xc\xe\xf" } },
1.1.1.4   root     1355:        { 193, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
                   1356:        { 203, L5, 10, H, 0,-1, KC_PAD_comma,           { "," } },
                   1357:        { 213, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
                   1358: 
                   1359:        // Enter だけ矩形でないので別処理するが
                   1360:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
                   1361:        { -1, -1, -1, -1, 0,-1, KC_enter,                       { EnterMark } },
                   1362: };
                   1363: 
1.1.1.16  root     1364: 
1.1.1.4   root     1365: //
1.1.1.6   root     1366: // ソフトウェアキーボード (ウィンドウ)
1.1.1.4   root     1367: //
                   1368: 
                   1369: // コンストラクタ
1.1.1.12  root     1370: WXSoftKeyWindow::WXSoftKeyWindow(wxWindow *parent, VMType vmtype)
1.1.1.7   root     1371:        : inherited(parent, wxID_ANY, _("Software Keyboard"))
1.1.1.4   root     1372: {
1.1.1.16  root     1373:        switch (vmtype) {
                   1374:         case VMType::X68030:
1.1.1.15  root     1375:                new WXX68kSoftKeyPanel(this);
1.1.1.16  root     1376:                break;
                   1377:         case VMType::LUNA1:
                   1378:                new WXLuna1SoftKeyPanel(this);
                   1379:                break;
                   1380:         case VMType::LUNA88K:
                   1381:                new WXLuna88kSoftKeyPanel(this);
                   1382:                break;
                   1383:         default:
                   1384:                assert(false);
1.1.1.6   root     1385:        }
1.1.1.4   root     1386: 
1.1.1.15  root     1387:        Fit();
1.1.1.4   root     1388: }
                   1389: 
                   1390: // デストラクタ
1.1.1.6   root     1391: WXSoftKeyWindow::~WXSoftKeyWindow()
1.1.1.4   root     1392: {
                   1393: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.