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

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: 
                      7: #include "wxsoftkey.h"
1.1.1.4   root        8: #include "wxcolor.h"
1.1.1.6   root        9: #include "wxmainview.h"
1.1       root       10: #include "wxtextscreen.h"
1.1.1.8   root       11: #include "wxuimessage.h"
1.1.1.4   root       12: #include "sram.h"
1.1       root       13: 
                     14: //
1.1.1.4   root       15: // ソフトウェアキーボード (パネル) 共通部分
1.1       root       16: //
                     17: 
1.1.1.4   root       18: // エンター記号。
                     19: // 描画の際にキー刻印文字列の半角文字数から描画幅を決定しており、
                     20: // エンター記号は半角2文字幅で描いているので実際の文字列も2文字にしておく。
                     21: // そうすると "\\n" が意味的にもちょうどいい。
                     22: // これは幅を算出するのに使うだけで表示はされない。
                     23: #define EnterMark      "\\n"
                     24: 
1.1       root       25: // イベントテーブル
1.1.1.4   root       26: wxBEGIN_EVENT_TABLE(WXSoftKeyPanel, inherited)
                     27:        EVT_LEFT_DOWN(WXSoftKeyPanel::OnLeftDown)
                     28:        EVT_LEFT_UP(WXSoftKeyPanel::OnLeftUp)
                     29:        EVT_LEFT_DCLICK(WXSoftKeyPanel::OnLeftDClick)
                     30:        EVT_RIGHT_DOWN(WXSoftKeyPanel::OnRightDown)
                     31:        EVT_PAINT(WXSoftKeyPanel::OnPaint)
1.1.1.9 ! root       32:        EVT_TIMER(wxID_ANY, WXSoftKeyPanel::OnTimer)
1.1       root       33: wxEND_EVENT_TABLE()
                     34: 
                     35: // コンストラクタ
1.1.1.4   root       36: WXSoftKeyPanel::WXSoftKeyPanel(wxWindow *parent,
1.1.1.6   root       37:        const std::vector<keydata_t>& keydata_, int u_width_, int u_height_)
1.1       root       38:        : inherited(parent)
1.1.1.6   root       39:        , keydata(keydata_)
1.1       root       40: {
1.1.1.9 ! root       41:        timer.SetOwner(this);
        !            42: 
1.1.1.4   root       43:        u_width  = u_width_;
                     44:        u_height = u_height_;
1.1.1.6   root       45: 
1.1.1.7   root       46:        DoSize();
                     47: 
1.1.1.9 ! root       48:        // 残光の初期化。
        !            49:        // persistence は keydata 分の配列ではなく共通キーコード分の配列。
        !            50:        // 使われない領域も多いが、共通キーコードから keydata 番号への逆引きは
        !            51:        // 面倒なので。
        !            52:        persistence.resize(KC_max);
        !            53:        std::fill(persistence.begin(), persistence.end(), 0);
        !            54: 
1.1.1.6   root       55:        // このパネルへのキー入力はメインビューへのキー入力と同じ。
1.1.1.9 ! root       56:        Connect(wxEVT_CHAR, wxCharEventHandler(WXMainView::OnChar), NULL,
        !            57:                gMainView);
1.1.1.6   root       58:        Connect(wxEVT_KEY_UP, wxKeyEventHandler(WXMainView::OnKeyUp), NULL,
                     59:                gMainView);
                     60:        Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(WXMainView::OnKeyDown), NULL,
                     61:                gMainView);
                     62: 
1.1.1.8   root       63:        // VM からの通知を受け取る
                     64:        WXUIMessage::Connect(UIMessage::KEYBOARD, this,
                     65:                wxCommandEventHandler(WXSoftKeyPanel::OnKeyChanged));
1.1       root       66: }
                     67: 
                     68: // デストラクタ
1.1.1.4   root       69: WXSoftKeyPanel::~WXSoftKeyPanel()
1.1       root       70: {
1.1.1.9 ! root       71:        // SHIFT キーのワンショットは解放する?
        !            72:        // (長押しは開放しない)
        !            73: 
        !            74:        timer.Stop();
        !            75: 
1.1.1.8   root       76:        WXUIMessage::Disconnect(UIMessage::KEYBOARD,
                     77:                wxCommandEventHandler(WXSoftKeyPanel::OnKeyChanged));
1.1       root       78: }
                     79: 
1.1.1.9 ! root       80: // color.Keytop の初期化(補間)。
        !            81: // num はキートップの種類の数。1 か 2
        !            82: void
        !            83: WXSoftKeyPanel::InitColorKeytop(int num)
        !            84: {
        !            85:        wxColour pressed = UD_BLUE;
        !            86: 
        !            87:        auto f = [](int a, int b, int x) {
        !            88:                return a * x / 100 + b * (100 - x) / 100;
        !            89:        };
        !            90: 
        !            91:        // Keytop[i][9] は押されたときの色
        !            92:        // Keytop[i][0] は押されていないときの色
        !            93:        for (int i = 0; i < num; i++) {
        !            94:                for (int j = 1; j < 10; j++) {
        !            95:                        int n = j * 100 / 9;
        !            96:                        color.Keytop[i][j] = wxColour(
        !            97:                                f(pressed.Red(), color.Keytop[i][0].Red(), n),
        !            98:                                f(pressed.Green(), color.Keytop[i][0].Green(), n),
        !            99:                                f(pressed.Blue(), color.Keytop[i][0].Blue(), n));
        !           100:                }
        !           101:        }
        !           102: }
        !           103: 
1.1       root      104: // フォントサイズ変更 (外部インタフェース)
                    105: void
1.1.1.5   root      106: WXSoftKeyPanel::SetFontSize(FontId new_fontid)
1.1       root      107: {
                    108:        // 同じなら何もしない
1.1.1.5   root      109:        if (fontid == new_fontid) {
1.1       root      110:                return;
                    111:        }
                    112: 
                    113:        // フォントを更新
1.1.1.5   root      114:        UpdateFont(new_fontid);
1.1       root      115: 
                    116:        // サイズ変更処理
                    117:        DoSize();
                    118: }
                    119: 
                    120: // サイズ変更処理
                    121: // サイズを変更したい時に呼ぶ (サイズが変更されたらではない)。
                    122: // ここではサイズは fontsize にのみ依存しているので、フォントサイズが
                    123: // 変化/確定した時に呼び出すこと。
                    124: void
1.1.1.4   root      125: WXSoftKeyPanel::DoSize()
1.1       root      126: {
1.1.1.5   root      127:        assert(fontid != FontId::None);
1.1       root      128: 
                    129:        // このパネル内の描画の基本単位
                    130:        unit = font_height / 4;
                    131: 
                    132:        // エンターキーだけ矩形でないのでここでリージョンを計算。
                    133:        // unit が確定したところで一回行う。
1.1.1.6   root      134:        // ただし SHIFT_R のキーコードはちょっと使いづらいので、ここでは SHIFT_R
                    135:        // を使わず [_] キーで代用する。
                    136:        //
                    137:        //   |   ^   |   \   |   BS  |
                    138:        //   |       |       |       |
                    139:        // --+---+---+--(A)--+------(B)
                    140:        //       |       |           |
                    141:        //       |   [   |           |
                    142:        //       |       |    Enter  |
                    143:        // --+---+---+--(F)-(E)      |
                    144:        //   |       |       |       |
                    145:        //   |   :   |   ]   |       |
                    146:        //   |       |       |       |
                    147:        // --+---+---+------(D)-----(C)
                    148:        //       |                   |
                    149:        //   _   |      SHIFT        |
1.1       root      150:        //
                    151:        const keydata_t& keybs = FindKeydata(KC_BS);
                    152:        const keydata_t& keyleft = FindKeydata(KC_bracketleft);
                    153:        const keydata_t& keyright = FindKeydata(KC_bracketright);
1.1.1.6   root      154:        const keydata_t& keyscore = FindKeydata(KC_underscore);
1.1       root      155:        // 各点のピクセル座標
                    156:        enter_points = {
                    157:                { keyleft.right() * unit, keyleft.y * unit },   // A
                    158:                { keybs.right() * unit, keyleft.y * unit },             // B
1.1.1.6   root      159:                { keybs.right() * unit, keyscore.y * unit },    // C
                    160:                { keyright.right() * unit, keyscore.y * unit }, // D
1.1       root      161:                { keyright.right() * unit, keyright.y * unit }, // E
                    162:                { keyleft.right() * unit, keyright.y * unit },  // F
                    163:        };
                    164:        // 当たり判定用のリージョン
                    165:        enter_region = wxRegion(enter_points.size(), enter_points.data());
                    166: 
                    167:        // コントロールの大きさを変更
1.1.1.4   root      168:        wxSize size(u_width * unit, u_height * unit);
1.1       root      169:        SetClientSize(size);
1.1.1.6   root      170:        SetMinClientSize(size);
1.1       root      171: 
                    172:        // ビットマップ作成
1.1.1.6   root      173:        bitmap.Create(size.x, size.y);
1.1       root      174: 
                    175:        // 再描画を指示
                    176:        Refresh();
                    177: }
                    178: 
1.1.1.9 ! root      179: void
        !           180: WXSoftKeyPanel::OnTimer(wxTimerEvent& event)
        !           181: {
        !           182:        Refresh();
        !           183: }
        !           184: 
1.1.1.8   root      185: // キー状態変更イベント (UIMessage)
1.1.1.9 ! root      186: //
        !           187: // キー状態変更イベントは、キーの状態が変わるたびに都度通知される。
        !           188: // ソフトウェアキーボード入力とパススルーモードの入力では、どのキーに変化
        !           189: // (押下 or 開放)があったかの情報は付属しない。各キーの押下状態は全キーを
        !           190: // 逐一調査することで判定する。人間時間で起きる事象なのでこの計算量は許容。
        !           191: // Char 入力モードの場合は、イベントのパラメータ引数 (GetInt() で取得可) に
        !           192: // 入力のあったキーの共通キーコードが入っている (複数のキーが同時に押される
        !           193: // 場合はキーの回数分のイベントが飛んでくる)。Char 入力モードにはキー開放
        !           194: // という概念はない。
1.1.1.6   root      195: void
1.1.1.8   root      196: WXSoftKeyPanel::OnKeyChanged(wxCommandEvent& event)
1.1.1.6   root      197: {
1.1.1.9 ! root      198:        // Char 入力モードでキーが押された場合は、共通キーコードが送られてくるので、
        !           199:        // persistence[] をここでセットする。
        !           200:        // Char 入力モードでは、キーの Make/Break が一瞬で終わるため、このイベント
        !           201:        // を受け取って Refresh() を発行 -> OnPaint() -> Draw() 内で IsPressed()
        !           202:        // を調べた頃にはタイミング問題でもうキーが離されている可能性があるので、
        !           203:        // 描画時に全キーを調べる方法は使えない。
        !           204:        uint keycode = event.GetInt();
        !           205:        if (keycode != 0) {
        !           206:                assert(keycode < persistence.size());
        !           207:                // 9 が減光時の初期値 (10 は減光しない点灯)
        !           208:                persistence[keycode] = 9;
1.1.1.6   root      209:        }
1.1.1.9 ! root      210: 
        !           211:        Refresh();
1.1.1.6   root      212: }
                    213: 
1.1       root      214: // 描画イベント (UI スレッドから呼ばれる)
                    215: void
1.1.1.4   root      216: WXSoftKeyPanel::OnPaint(wxPaintEvent& event)
1.1       root      217: {
                    218:        // メモリ DC に描画
                    219:        wxMemoryDC memDC;
1.1.1.6   root      220:        memDC.SelectObject(bitmap);
1.1       root      221:        Draw(memDC);
                    222: 
                    223:        // 実画面 DC にコピー
                    224:        wxPaintDC dstDC(this);
1.1.1.6   root      225:        wxSize size = bitmap.GetSize();
                    226:        dstDC.Blit(0, 0, size.x, size.y, &memDC, 0, 0);
1.1       root      227: }
                    228: 
                    229: // 描画本体
                    230: void
1.1.1.4   root      231: WXSoftKeyPanel::Draw(wxDC& dc)
1.1       root      232: {
1.1.1.9 ! root      233:        bool timer_start = false;
        !           234: 
        !           235:        // キー刻印の表示更新用に修飾キーの状態を更新。
        !           236:        // 本来は IsShift() だけで判定すべきだが、Char 入力モードでいずれかの
        !           237:        // SHIFT キーが減光中は SHIFT 刻印を継続してみるのはどうか。
        !           238:        // 0 まで待つとうちの環境だと消灯した少し後に刻印が戻るように見えるため、
        !           239:        // ある程度暗くなったところでもう切り替えてみる。閾値は適当。
        !           240:        if ((2 < persistence[KC_SHIFT_L] && persistence[KC_SHIFT_L] < 10) ||
        !           241:            (2 < persistence[KC_SHIFT_R] && persistence[KC_SHIFT_R] < 10) ||
        !           242:                (2 < persistence[KC_SHIFT]   && persistence[KC_SHIFT]   < 10) ||
        !           243:                gKeyboard->IsShift())
        !           244:        {
        !           245:                modifier = ModShift;
        !           246:        } else {
        !           247:                modifier = ModNormal;
        !           248:        }
        !           249: 
1.1.1.4   root      250:        dc.SetPen(wxPen(color.Background));
                    251:        dc.SetBrush(wxBrush(color.Background));
1.1       root      252:        dc.DrawRectangle(wxPoint(0, 0), GetSize());
                    253: 
1.1.1.4   root      254:        dc.SetPen(color.Text);
                    255:        SetTextForeColor(color.Text);
1.1.1.6   root      256:        for (const auto& key : keydata) {
1.1.1.9 ! root      257:                int c = persistence[key.keycode];
        !           258:                if (0 < c && c < 10) {
        !           259:                        // Char 入力モードで減光中
        !           260:                        c--;
        !           261:                        timer_start = true;
1.1       root      262:                } else {
1.1.1.9 ! root      263:                        // そうでない場合に限り、現在の状態を問い合わせる
        !           264:                        bool is_pressed = gKeyboard->IsPressed(key.keycode);
        !           265:                        if (is_pressed) {
        !           266:                                // 押されている
        !           267:                                c = 10;
        !           268:                        } else {
        !           269:                                // 押されていない
        !           270:                                c = 0;
        !           271:                        }
        !           272:                }
        !           273:                // persistence[] は 10 が(減光しない)点灯、9..1 が減光中を示す。
        !           274:                persistence[key.keycode] = c;
        !           275:                // ただし色配列は 0..9 で 9 が最大点灯色
        !           276:                if (c > 9) {
        !           277:                        c = 9;
1.1       root      278:                }
                    279: 
1.1.1.9 ! root      280:                SetTextBackColor(color.Keytop[key.coltype][c]);
        !           281:                dc.SetBrush(color.Keytop[key.coltype][c]);
        !           282: 
1.1       root      283:                // エンターキーだけ枠の描き方が違うので別処理
                    284:                if (__predict_false(key.x < 0)) {
                    285:                        DrawEnterKey(dc);
                    286:                } else {
                    287:                        DrawKey(dc, key);
                    288:                }
                    289:        }
                    290: 
1.1.1.9 ! root      291:        if (timer_start) {
        !           292:                timer.Start(25);
        !           293:        } else {
        !           294:                timer.Stop();
        !           295:        }
1.1.1.6   root      296: 
1.1.1.4   root      297: #if 0
                    298:        // X68k キーボードだとどこに表示するか
                    299:        SetTextBackColor(color.Background);
1.1.1.2   root      300:        wxString utfstr(wxT("右クリックで長押し"));
1.1       root      301:        const char *sjis = (const char *)utfstr.mb_str(conv);
                    302:        DrawStringSJIS(dc, 190 * unit, 2 * unit, sjis, TA::Disable);
1.1.1.4   root      303: #endif
1.1       root      304: }
                    305: 
                    306: // 指定のキーを一つ (枠から刻印まで) 描画する。
                    307: void
1.1.1.4   root      308: WXSoftKeyPanel::DrawKey(wxDC& dc, const keydata_t& key)
1.1       root      309: {
                    310:        // 枠
                    311:        wxPoint pt(key.x * unit, key.y * unit);
                    312:        wxSize sz(key.w * unit + 1, key.h * unit + 1);
                    313:        dc.DrawRectangle(pt, sz);
                    314: 
                    315:        // 刻印を選択
                    316:        const char *disp = key.disp[modifier];
                    317:        if (disp == NULL) {
                    318:                disp = key.disp[0];
                    319:        }
                    320: 
                    321:        // Shift_JIS に変換
                    322:        wxString utfstr(disp, wxConvUTF8);
                    323:        const char *sjis = (const char *)utfstr.mb_str(conv);
1.1.1.4   root      324:        // 改行があれば2行に分割
                    325:        char sjis1[8] {};
                    326:        char sjis2[8] {};
                    327:        int sjislen;
                    328:        int row;
                    329:        const char *lf = strchr(sjis, '\n');
                    330:        if (lf == NULL) {
                    331:                // 1行なら、Shift_JIS での文字数は半角換算の文字数と一致する。
                    332:                sjislen = strlen(sjis);
                    333:                row = 1;
                    334:        } else {
                    335:                // 2行に分割。センタリングは1行目の長さだけで調べる。
                    336:                strncpy(sjis1, sjis, lf - sjis);
                    337:                strcpy(sjis2, lf + 1);
                    338:                sjislen = strlen(sjis1);
                    339:                row = 2;
                    340:        }
1.1       root      341: 
                    342:        // センタリング
                    343:        int x = key.x + (key.w - sjislen * 2) / 2;
1.1.1.4   root      344:        int y = key.y + (key.h - row * 4) / 2;
1.1       root      345: 
1.1.1.4   root      346:        // LED を描画 (機種によって色々違うので個別クラス側で処理)
                    347:        if (key.led >= 0) {
1.1       root      348:                const wxPen oldpen = dc.GetPen();
                    349:                const wxBrush oldbrush = dc.GetBrush();
1.1.1.4   root      350: 
                    351:                y += DrawLED(dc, key);
                    352: 
1.1       root      353:                dc.SetPen(oldpen);
                    354:                dc.SetBrush(oldbrush);
                    355:        }
                    356: 
                    357:        // 文字を描画
                    358:        pt = wxPoint(x * unit + 1, y * unit + 1);
1.1.1.4   root      359:        if (strcmp(disp, EnterMark) == 0) {
1.1       root      360:                DrawEnterMark(dc, pt);
                    361:        } else {
1.1.1.4   root      362:                if (lf == NULL) {
                    363:                        // 1行の場合
                    364:                        DrawStringSJIS(dc, pt.x, pt.y, sjis);
                    365:                } else {
                    366:                        // 2行の場合
                    367:                        DrawStringSJIS(dc, pt.x, pt.y, sjis1);
                    368:                        pt.y += 4 * unit;
                    369:                        DrawStringSJIS(dc, pt.x, pt.y, sjis2);
                    370:                }
1.1       root      371:        }
                    372: }
                    373: 
                    374: // エンターキー
                    375: void
1.1.1.4   root      376: WXSoftKeyPanel::DrawEnterKey(wxDC& dc)
1.1       root      377: {
                    378:        // エンターキーを描画
                    379:        dc.DrawPolygon(enter_points.size(), enter_points.data());
                    380: 
                    381:        // エンター記号を描画
                    382:        DrawEnterMark(dc, wxPoint(
                    383:                (enter_points[0].x + enter_points[1].x) / 2 - (4 / 2),
                    384:                (enter_points[1].y + enter_points[2].y) / 2 - (4 / 2)));
                    385: }
                    386: 
                    387: // 指定の位置にエンター記号を描画する (エンターキー全体の描画ではない)。
                    388: // メインキーとテンキーの両方で同じ図柄を使う。
                    389: // 大きさは (3unit, 4unit) なので実質全角1文字分くらい。
                    390: void
1.1.1.4   root      391: WXSoftKeyPanel::DrawEnterMark(wxDC& dc, const wxPoint& basep)
1.1       root      392: {
                    393:        // エンター記号は幅 3 unit、高さ 4 unit。
                    394:        //    +0 +1 +2 +3
                    395:        // +0 .. .. .. 1.
                    396:        //    .. .. .. 1.
                    397:        // +1 .. .. .. 1.
                    398:        //    .. .. .. 1.
                    399:        // +2 .. 1. .. 1.
                    400:        //    .1 .. .. 1.
                    401:        // +3 11 11 11 1.
                    402:        //    .1 .. .. ..
                    403:        // +4 .. 1. .. ..
                    404:        //    .. .. .. ..
                    405:        static const std::vector<std::pair<int,int>> entermark {
                    406:                {  3, 0 },
                    407:                {  3, 3 },      // │
                    408:                {  0, 3 },      // ─
                    409:                {  1, 2 },      // /
                    410:                {  0, 3 },      // (一筆書きなので戻る)
                    411:                {  1, 4 },      // \
                    412:        };
                    413:        for (int i = 1; i < entermark.size(); i++) {
                    414:                auto start = entermark[i - 1];
                    415:                auto end   = entermark[i];
                    416:                wxPoint startp(start.first * unit, start.second * unit);
                    417:                wxPoint endp(end.first * unit, end.second * unit);
                    418:                dc.DrawLine(basep + startp, basep + endp);
                    419:        }
                    420: }
                    421: 
                    422: // keycode に対応する keydata を返す
                    423: const keydata_t&
1.1.1.4   root      424: WXSoftKeyPanel::FindKeydata(uint keycode) const
1.1       root      425: {
1.1.1.6   root      426:        for (const auto& key : keydata) {
1.1       root      427:                if (key.keycode == keycode) {
                    428:                        return key;
                    429:                }
                    430:        }
                    431:        // 見付からないはずはない
1.1.1.3   root      432:        assertmsg(0, "keycode %d not found", keycode);
1.1       root      433: }
                    434: 
1.1.1.9 ! root      435: // keycode が SHIFT キーなら true を返す
        !           436: // (SHIFT キーが押されているかとかではない)
        !           437: /*static*/ bool
        !           438: WXSoftKeyPanel::IsShiftKey(uint keycode)
        !           439: {
        !           440:        if (keycode == KC_SHIFT_L ||
        !           441:            keycode == KC_SHIFT_R ||
        !           442:            keycode == KC_SHIFT)
        !           443:        {
        !           444:                return true;
        !           445:        }
        !           446:        return false;
        !           447: }
        !           448: 
1.1       root      449: // マウス左クリック (Down) イベント
                    450: void
1.1.1.4   root      451: WXSoftKeyPanel::OnLeftDown(wxMouseEvent& event)
1.1       root      452: {
1.1.1.5   root      453:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      454:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      455: 
1.1.1.9 ! root      456:        if (key != NULL) {
        !           457:                DoLeftDown(key);
        !           458:        }
1.1       root      459: }
                    460: 
                    461: // マウス左クリック (Down) 処理
                    462: void
1.1.1.4   root      463: WXSoftKeyPanel::DoLeftDown(const keydata_t *key)
1.1       root      464: {
1.1.1.9 ! root      465:        assert(key);
        !           466: 
        !           467:        // SHIFT キーの左クリックはトグル状動作。
        !           468:        // SHIFT 状態で押すと、すべての SHIFT キーを開放。
        !           469:        // 非 SHIFT 状態で押すと、次のキー押下までこの SHIFT キーを押下維持。
        !           470:        if (IsShiftKey(key->keycode)) {
        !           471:                if (gKeyboard->IsShift()) {
        !           472:                        // SHIFT 状態で SHIFT キーが押されたのですべての SHIFT キーを開放
        !           473:                        if (key->keycode == KC_SHIFT) {
        !           474:                                KeyUp(*key);
        !           475:                        } else {
        !           476:                                KeyUp(FindKeydata(KC_SHIFT_L));
        !           477:                                KeyUp(FindKeydata(KC_SHIFT_R));
        !           478:                        }
        !           479:                } else {
        !           480:                        // 非 SHIFT 状態で SHIFT キーが押されたのでこのキーを押下
        !           481:                        KeyDown(*key);
        !           482:                        shift_hold = false;
        !           483:                }
        !           484: 
        !           485:                // SHIFT キーなら LeftUp では何もしない
        !           486:                leftdown_key = NULL;
        !           487:        } else {
        !           488:                // SHIFT 以外のキーは押下して LeftUp のために覚えておく
1.1.1.6   root      489:                KeyDown(*key);
                    490:                leftdown_key = key;
1.1       root      491:        }
                    492: }
                    493: 
                    494: // マウス左クリック (Up) イベント
                    495: void
1.1.1.4   root      496: WXSoftKeyPanel::OnLeftUp(wxMouseEvent& event)
1.1       root      497: {
                    498:        // Up 時は、これが起きた地点のキーコードではなく
                    499:        // 直近に LeftDown したキーコードをターゲットにする。
1.1.1.4   root      500:        const keydata_t *key = leftdown_key;
1.1       root      501: 
1.1.1.4   root      502:        if (key != NULL) {
1.1.1.6   root      503:                KeyUp(*key);
1.1.1.9 ! root      504: 
        !           505:                // キーが離された時、長押しでない SHIFT キーがあれば開放
        !           506:                if (gKeyboard->IsShift() && shift_hold == false) {
        !           507:                        // XXX どの SHIFT が存在するのか分からないのがなんかアレ
        !           508:                        if (gKeyboard->IsPressed(KC_SHIFT_L)) {
        !           509:                                KeyUp(FindKeydata(KC_SHIFT_L));
        !           510:                        }
        !           511:                        if (gKeyboard->IsPressed(KC_SHIFT_R)) {
        !           512:                                KeyUp(FindKeydata(KC_SHIFT_R));
        !           513:                        }
        !           514:                        if (gKeyboard->IsPressed(KC_SHIFT)) {
        !           515:                                KeyUp(FindKeydata(KC_SHIFT));
        !           516:                        }
        !           517:                }
1.1       root      518:        }
1.1.1.9 ! root      519: 
1.1.1.4   root      520:        leftdown_key = NULL;
1.1       root      521: }
                    522: 
                    523: // マウス左ダブルクリックイベント
                    524: // ダブルクリックという操作に特別何かを割り当ててはいないが、
                    525: // キーを連打するとその間隔によってはダブルクリックと扱われるため、
                    526: // 受け取ってここで処理する。
                    527: //
                    528: // DClick イベントは LeftDown、LeftUp、LeftDClick、LeftUp の順で
                    529: // 飛んでくるので、ここでは2回目の押下だけ処理すればよい。というか
                    530: // 処理自体は LeftDown とまったく同じになるので、イベントテーブルで
                    531: // 直接 EVT_LEFT_DCLICK => OnLeftDown に割り付けることも出来そうだが
                    532: // デバッグが紛らわしくなりそうなので独立したイベントとしておく。
                    533: void
1.1.1.4   root      534: WXSoftKeyPanel::OnLeftDClick(wxMouseEvent& event)
1.1       root      535: {
1.1.1.5   root      536:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      537:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      538: 
1.1.1.9 ! root      539:        if (key != NULL) {
        !           540:                DoLeftDown(key);
        !           541:        }
1.1       root      542: }
                    543: 
                    544: // マウス右クリック (Down) イベント
                    545: // 長押し開始/解除。
                    546: // 右クリックのほうは Down だけで Up は使わない。
                    547: void
1.1.1.4   root      548: WXSoftKeyPanel::OnRightDown(wxMouseEvent& event)
1.1       root      549: {
1.1.1.5   root      550:        const wxPoint& pt = event.GetPosition();
1.1.1.4   root      551:        const keydata_t *key = GetKeydataFromPoint(pt);
1.1       root      552: 
1.1.1.4   root      553:        if (key != NULL) {
                    554:                uint code = key->keycode;
1.1.1.6   root      555:                if (gKeyboard->IsPressed(code)) {
1.1       root      556:                        // 押されていたら開放
1.1.1.4   root      557:                        KeyUp(*key);
1.1       root      558:                } else {
                    559:                        // 押されてなければ長押し開始
1.1.1.4   root      560:                        KeyDown(*key);
1.1.1.9 ! root      561: 
        !           562:                        if (IsShiftKey(key->keycode)) {
        !           563:                                shift_hold = true;
        !           564:                        }
1.1       root      565:                }
                    566:        }
                    567: }
                    568: 
1.1.1.4   root      569: // 座標からキーデータを返す。
                    570: // キーに当たっていなければ NULL を返す。
                    571: const keydata_t *
                    572: WXSoftKeyPanel::GetKeydataFromPoint(const wxPoint& pt) const
1.1       root      573: {
1.1.1.4   root      574:        // エンターキーだけ先に別判定
                    575:        if (enter_region.Contains(pt) == wxInRegion) {
                    576:                return &FindKeydata(KC_enter);
                    577:        }
1.1       root      578: 
1.1.1.6   root      579:        for (const auto& key : keydata) {
1.1.1.4   root      580:                if (key.x < 0) {
                    581:                        continue;
1.1       root      582:                }
1.1.1.4   root      583:                // 始点と幅の +1/-1 は罫線の分
                    584:                wxRect rect(
                    585:                        (key.x * unit) + 1,
                    586:                        (key.y * unit) + 1,
                    587:                        (key.w * unit) - 1,
                    588:                        (key.h * unit) - 1);
                    589:                if (rect.Contains(pt)) {
                    590:                        return &key;
1.1       root      591:                }
1.1.1.4   root      592:        }
                    593:        return NULL;
                    594: }
                    595: 
1.1.1.6   root      596: // このキーが押された処理
                    597: void
                    598: WXSoftKeyPanel::KeyDown(const keydata_t& key)
                    599: {
                    600:        uint code = key.keycode;
                    601: 
1.1.1.9 ! root      602:        // VM に通知 (Keyboard がホストに通知する)
1.1.1.6   root      603:        gKeyboard->MakeKey(code);
                    604: }
                    605: 
                    606: // このキーが放された処理
                    607: void
                    608: WXSoftKeyPanel::KeyUp(const keydata_t& key)
                    609: {
                    610:        uint code = key.keycode;
                    611: 
1.1.1.9 ! root      612:        // VM に通知 (Keyboard がホストに通知する)
1.1.1.6   root      613:        gKeyboard->BreakKey(code);
                    614: }
                    615: 
                    616: 
1.1.1.4   root      617: //
                    618: // LUNA ソフトウェアキーボード (パネル)
                    619: //
                    620: 
                    621: // コンストラクタ
                    622: WXLunaSoftKeyPanel::WXLunaSoftKeyPanel(wxWindow *parent)
1.1.1.6   root      623:        : inherited(parent, keydata, 226, 54)
1.1.1.4   root      624: {
                    625:        // LUNA では
                    626:        // BS キーの左隣 (0x5c) は円記号ではなくバックスラッシュ。
                    627:        // それを SHIFT したやつ(0x7c) は破線でないパイプ。
                    628:        // そのもう一つ左隣 (0x7e) はオーバーラインではなくチルダ。
                    629:        SetGlyph5C(true);
                    630:        SetGlyph7E(true);
                    631: 
1.1.1.9 ! root      632:        // 白黒モデル共通
        !           633:        color.Border = *wxBLACK;
        !           634:        color.LED[0] = UD_RED;
        !           635: 
1.1.1.4   root      636:        // キートップの濃淡はユニバーサルデザインの推奨色ではないけど
                    637:        // ここは見分けを付けるためではなくただのデザインなので。
                    638:        if (1) {
                    639:                // 白モデル
1.1.1.9 ! root      640:                color.Background        = UD_LIGHT_GREY;        // 現物新品は何色だったんだろう
        !           641:                color.Text                      = *wxBLACK;
        !           642:                color.Keytop[0][0]      = *wxWHITE;
        !           643:                color.Keytop[1][0]      = wxColour(200, 200, 203);
1.1.1.4   root      644:        } else {
                    645:                // 黒モデル
1.1.1.9 ! root      646:                color.Background        = *wxBLACK;
        !           647:                color.Text                      = *wxWHITE;
        !           648:                color.Keytop[0][0]      = wxColour(50, 50, 53);
        !           649:                color.Keytop[1][0]      = *wxBLACK;
1.1.1.4   root      650:        }
1.1.1.9 ! root      651:        InitColorKeytop(2);
1.1.1.4   root      652: }
                    653: 
                    654: // デストラクタ
                    655: WXLunaSoftKeyPanel::~WXLunaSoftKeyPanel()
                    656: {
                    657: }
                    658: 
                    659: // LED を描画して刻印描画のための y offset を返す。
                    660: int
                    661: WXLunaSoftKeyPanel::DrawLED(wxDC& dc, const keydata_t& key)
                    662: {
                    663:        const std::vector<bool>& led = gKeyboard->GetLED();
                    664: 
                    665:        if (led[key.led]) {
                    666:                // 点灯時は赤、枠は黒
                    667:                dc.SetPen(color.Border);
                    668:                dc.SetBrush(color.LED[0]);
1.1       root      669:        } else {
1.1.1.4   root      670:                // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6   root      671:                // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
                    672:                dc.SetPen(UD_GREY);
1.1.1.9 ! root      673:                dc.SetBrush(color.Keytop[key.coltype][0]);
1.1       root      674:        }
                    675: 
1.1.1.4   root      676:        // LED を左肩に描く
                    677:        wxPoint pt = wxPoint(key.x * unit + 2, key.y * unit + 2);
                    678:        wxSize sz = wxSize(4 * unit - 2, 3 * unit - 2);
                    679:        dc.DrawRectangle(pt, sz);
                    680: 
                    681:        // そのため文字は少し下げる
                    682:        return +1;
                    683: }
                    684: 
1.1       root      685: // キーデータ
                    686: #define H       (8)    // キーの高さ
                    687: #define L0      (2)    // ファンクションキーの行
                    688: #define L1     (12)    // ESC の行
                    689: #define L2     (20)    // TAB の行
                    690: #define L3     (28)    // CTRL の行
                    691: #define L4     (36)    // SHIFT の行
                    692: #define L5     (44)    // space の行
                    693: /*static*/ std::vector<keydata_t>
                    694: WXLunaSoftKeyPanel::keydata {
1.1.1.4   root      695:        //                +---- キートップの色(1:濃)
                    696:        //                |  +- 0 以上なら LED 番号
                    697:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
                    698:        {   2, L0, 15, H, 1,-1, KC_F1,                          { "PF1" } },
                    699:        {  17, L0, 15, H, 1,-1, KC_F2,                          { "PF2" } },
                    700:        {  32, L0, 15, H, 1,-1, KC_F3,                          { "PF3" } },
                    701:        {  47, L0, 15, H, 1,-1, KC_F4,                          { "PF4" } },
                    702:        {  62, L0, 15, H, 1,-1, KC_F5,                          { "PF5" } },
                    703:        {  81, L0, 15, H, 1,-1, KC_F6,                          { "PF6" } },
                    704:        {  96, L0, 15, H, 1,-1, KC_F7,                          { "PF7" } },
                    705:        { 111, L0, 15, H, 1,-1, KC_F8,                          { "PF8" } },
                    706:        { 126, L0, 15, H, 1,-1, KC_F9,                          { "PF9" } },
                    707:        { 141, L0, 15, H, 1,-1, KC_F10,                         { "PF10" } },
                    708: 
                    709:        {   2, L1, 12, H, 1,-1, KC_ESC,                         { "ESC" } },
                    710:        {  14, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
                    711:        {  24, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
                    712:        {  34, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
                    713:        {  44, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
                    714:        {  54, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
                    715:        {  64, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
                    716:        {  74, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
                    717:        {  84, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
                    718:        {  94, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
                    719:        { 104, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
                    720:        { 114, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
                    721:        { 124, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
                    722:        { 134, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
                    723:        { 144, L1, 12, H, 1,-1, KC_BS,                          { "BS" } },
                    724: 
                    725:        {   2, L2, 17, H, 1,-1, KC_TAB,                         { "TAB" } },
                    726:        {  19, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
                    727:        {  29, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
                    728:        {  39, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
                    729:        {  49, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
                    730:        {  59, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
                    731:        {  69, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
                    732:        {  79, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
                    733:        {  89, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
                    734:        {  99, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
                    735:        { 109, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
                    736:        { 119, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
                    737:        { 129, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
                    738: 
                    739:        {   2, L3, 20, H, 1,-1, KC_CTRL,                        { "CTRL" } },
                    740:        {  22, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
                    741:        {  32, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
                    742:        {  42, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
                    743:        {  52, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
                    744:        {  62, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
                    745:        {  72, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
                    746:        {  82, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
                    747:        {  92, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
                    748:        { 102, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
                    749:        { 112, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
                    750:        { 122, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
                    751:        { 132, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
                    752: 
                    753:        {   2, L4, 25, H, 1,-1, KC_SHIFT_L,                     { "SHIFT" } },
                    754:        {  27, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
                    755:        {  37, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
                    756:        {  47, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
                    757:        {  57, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
                    758:        {  67, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
                    759:        {  77, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
                    760:        {  87, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
                    761:        {  97, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
                    762:        { 107, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
                    763:        { 117, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
                    764:        { 127, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
                    765:        { 137, L4, 19, H, 1,-1, KC_SHIFT_R,                     { "SHIFT" } },
                    766: 
                    767:        {   2, L5, 20, H, 1,-1, KC_VALID,                       { "確定" } },
                    768:        {  22, L5, 10, H, 1,-1, KC_SF,                          { "前面" } },
                    769:        {  32, L5, 10, H, 1, 1, KC_CAPS,                        { "CAP" } },
                    770:        {  42, L5, 80, H, 0,-1, KC_space,                       { " " } },
                    771:        { 122, L5, 10, H, 1, 0, KC_kana,                        { "かな" } },
                    772:        { 132, L5, 24, H, 1,-1, KC_XFER,                        { "変換" } },
1.1       root      773: 
                    774:        // カーソルキー島
1.1.1.4   root      775:        { 160, L1, 10, H, 1,-1, KC_PF11,                        { "消去" } },
                    776:        { 170, L1, 10, H, 1,-1, KC_PF12,                        { "呼出" } },
                    777:        { 160, L2, 10, H, 1,-1, KC_PF13,                        { "文節\n←" } },
                    778:        { 170, L2, 10, H, 1,-1, KC_PF14,                        { "文節\n→" } },
                    779:        { 160, L3, 20, H, 1,-1, KC_up,                          { "↑" } },
                    780:        { 160, L4, 10, H, 1,-1, KC_left,                        { "←" } },
                    781:        { 170, L4, 10, H, 1,-1, KC_right,                       { "→" } },
                    782:        { 160, L5, 20, H, 1,-1, KC_down,                        { "↓" } },
1.1       root      783: 
                    784:        // テンキー島
1.1.1.4   root      785:        { 184, L1, 10, H, 1,-1, KC_DEL,                         { "DEL" } },
                    786:        { 194, L1, 10, H, 1,-1, KC_PAD_plus,            { "+" } },
                    787:        { 204, L1, 10, H, 1,-1, KC_PAD_minus,           { "-" } },
                    788:        { 214, L1, 10, H, 1,-1, KC_PAD_multiply,        { "*" } },
                    789: 
                    790:        { 184, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
                    791:        { 194, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
                    792:        { 204, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
                    793:        { 214, L2, 10, H, 1,-1, KC_PAD_divide,          { "/" } },
                    794: 
                    795:        { 184, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
                    796:        { 194, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
                    797:        { 204, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
                    798:        { 214, L3, 10, H, 1,-1, KC_PAD_equal,           { "=" } },
                    799: 
                    800:        { 184, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
                    801:        { 194, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
                    802:        { 204, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
                    803:        { 214, L4, 10, H, 1,-1, KC_PAD_comma,           { "," } },
                    804: 
                    805:        { 184, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
                    806:        { 194, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
                    807:        { 204, L5, 20, H, 1,-1, KC_PAD_enter,           { EnterMark } },
1.1       root      808: 
                    809:        // Enter だけ矩形でないので別処理するが
                    810:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
1.1.1.4   root      811:        { -1, -1, -1, -1, 1,-1, KC_enter,                       { EnterMark } },
1.1       root      812: };
                    813: 
                    814: 
                    815: //
1.1.1.4   root      816: // X68k ソフトウェアキーボード (パネル)
                    817: //
                    818: 
                    819: // コンストラクタ
                    820: WXX68kSoftKeyPanel::WXX68kSoftKeyPanel(wxWindow *parent)
1.1.1.6   root      821:        : inherited(parent, keydata, 235, 54)
1.1.1.4   root      822: {
                    823:        // X68k では SRAM 設定に同期させる。
                    824:        uint8 sw = gSRAM->Peek8(0xed0059);
                    825:        SetGlyph5C((sw & 0x01));
                    826:        SetGlyph7E((sw & 0x02));
                    827:        SetGlyph7C((sw & 0x04));
                    828: 
                    829:        // とりあえず黒のみ
1.1.1.9 ! root      830:        color.Background        = wxColour(50, 50, 53);
        !           831:        color.Text                      = *wxWHITE;
        !           832:        color.Border            = *wxBLACK;
        !           833:        color.LED[0]            = UD_RED;
        !           834:        color.LED[1]            = UD_YELLOW_GREEN;
        !           835:        color.Keytop[0][0]      = *wxBLACK;
        !           836:        InitColorKeytop(1);
1.1.1.4   root      837: }
                    838: 
                    839: // デストラクタ
                    840: WXX68kSoftKeyPanel::~WXX68kSoftKeyPanel()
                    841: {
                    842: }
                    843: 
                    844: // LED を描画して刻印描画のための y offset を返す。
                    845: int
                    846: WXX68kSoftKeyPanel::DrawLED(wxDC& dc, const keydata_t& key)
                    847: {
                    848:        const std::vector<bool>& led = gKeyboard->GetLED();
                    849: 
                    850:        // 色を選択
                    851:        // idx  刻印  色
                    852:        // ----------------
                    853:        //  0   かな  赤
                    854:        //  1   ローマ       赤
                    855:        //  2   コード       赤
                    856:        //  3   CAPS    赤
                    857:        //  4   INS             赤
                    858:        //  5   ひら  緑
                    859:        //  6   全角  緑
                    860:        if (led[key.led]) {
                    861:                int n = (key.led < 5) ? 0 : 1;
                    862:                dc.SetPen(color.LED[n]);
                    863:                dc.SetBrush(color.LED[n]);
                    864:        } else {
                    865:                // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6   root      866:                // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
                    867:                dc.SetPen(UD_GREY);
1.1.1.9 ! root      868:                dc.SetBrush(color.Keytop[key.coltype][0]);
1.1.1.4   root      869:        }
                    870: 
                    871:        // LED は中央前方(画面でいうと下)
                    872:        wxPoint pt = wxPoint((key.x + 3) * unit, (key.y + key.h - 2) * unit);
                    873:        wxSize sz = wxSize(4 * unit, 2 * unit);
                    874:        dc.DrawRectangle(pt, sz);
                    875: 
                    876:        // そのため文字は少し上げる
                    877:        return -1;
                    878: }
                    879: 
                    880: #define LF (L0 + 2)            // ファンクションキーは少し低い(横長い)
                    881: #define HT (H * 2)             // 縦2倍角のキー
                    882: /*static*/ std::vector<keydata_t>
                    883: WXX68kSoftKeyPanel::keydata {
                    884:        //                   +- 0以上なら LED 番号
                    885:        //  X   Y   W  H  C  L  KeyCode                         通常  SHIFT
1.1.1.7   root      886:        {   2, L0, 10, H, 0,-1, KC_BREAK,                       { "\x4\x5\x6\x7" } },
1.1.1.4   root      887:        {  15, L0, 10, H, 0,-1, KC_COPY,                        { "COPY" } },
                    888:        {  29, LF, 12, 6, 0,-1, KC_F1,                          { "F1" } },
                    889:        {  41, LF, 12, 6, 0,-1, KC_F2,                          { "F2" } },
                    890:        {  53, LF, 12, 6, 0,-1, KC_F3,                          { "F3" } },
                    891:        {  65, LF, 12, 6, 0,-1, KC_F4,                          { "F4" } },
                    892:        {  77, LF, 13, 6, 0,-1, KC_F5,                          { "F5" } },
                    893:        {  94, LF, 13, 6, 0,-1, KC_F6,                          { "F6" } },
                    894:        { 106, LF, 12, 6, 0,-1, KC_F7,                          { "F7" } },
                    895:        { 118, LF, 12, 6, 0,-1, KC_F8,                          { "F8" } },
                    896:        { 130, LF, 12, 6, 0,-1, KC_F9,                          { "F9" } },
                    897:        { 142, LF, 13, 6, 0,-1, KC_F10,                         { "F10" } },
                    898: 
                    899:        {   2, L1, 10, H, 0,-1, KC_ESC,                         { "ESC" } },
                    900:        {  12, L1, 10, H, 0,-1, KC_1,                           { "1",  "!" } },
                    901:        {  22, L1, 10, H, 0,-1, KC_2,                           { "2",  "\"" } },
                    902:        {  32, L1, 10, H, 0,-1, KC_3,                           { "3",  "#" } },
                    903:        {  42, L1, 10, H, 0,-1, KC_4,                           { "4",  "$" } },
                    904:        {  52, L1, 10, H, 0,-1, KC_5,                           { "5",  "%" } },
                    905:        {  62, L1, 10, H, 0,-1, KC_6,                           { "6",  "&" } },
                    906:        {  72, L1, 10, H, 0,-1, KC_7,                           { "7",  "'" } },
                    907:        {  82, L1, 10, H, 0,-1, KC_8,                           { "8",  "(" } },
                    908:        {  92, L1, 10, H, 0,-1, KC_9,                           { "9",  ")" } },
                    909:        { 102, L1, 10, H, 0,-1, KC_0,                           { "0",  " " } },
                    910:        { 112, L1, 10, H, 0,-1, KC_minus,                       { "-",  "=" } },
                    911:        { 122, L1, 10, H, 0,-1, KC_circum,                      { "^",  "~" } },
                    912:        { 132, L1, 10, H, 0,-1, KC_backslash,           { "\\", "|" } },
                    913:        { 142, L1, 13, H, 0,-1, KC_BS,                          { "BS" } },
                    914: 
                    915:        {   2, L2, 16, H, 0,-1, KC_TAB,                         { "TAB" } },
                    916:        {  18, L2, 10, H, 0,-1, KC_Q,                           { "q",  "Q" } },
                    917:        {  28, L2, 10, H, 0,-1, KC_W,                           { "w",  "W" } },
                    918:        {  38, L2, 10, H, 0,-1, KC_E,                           { "e",  "E" } },
                    919:        {  48, L2, 10, H, 0,-1, KC_R,                           { "r",  "R" } },
                    920:        {  58, L2, 10, H, 0,-1, KC_T,                           { "t",  "T" } },
                    921:        {  68, L2, 10, H, 0,-1, KC_Y,                           { "y",  "Y" } },
                    922:        {  78, L2, 10, H, 0,-1, KC_U,                           { "u",  "U" } },
                    923:        {  88, L2, 10, H, 0,-1, KC_I,                           { "i",  "I" } },
                    924:        {  98, L2, 10, H, 0,-1, KC_O,                           { "o",  "O" } },
                    925:        { 108, L2, 10, H, 0,-1, KC_P,                           { "p",  "P" } },
                    926:        { 118, L2, 10, H, 0,-1, KC_at,                          { "@",  "`" } },
                    927:        { 128, L2, 10, H, 0,-1, KC_bracketleft,         { "[",  "{" } },
                    928: 
                    929:        {   2, L3, 19, H, 0,-1, KC_CTRL,                        { "CTRL" } },
                    930:        {  21, L3, 10, H, 0,-1, KC_A,                           { "a",  "A" } },
                    931:        {  31, L3, 10, H, 0,-1, KC_S,                           { "s",  "S" } },
                    932:        {  41, L3, 10, H, 0,-1, KC_D,                           { "d",  "D" } },
                    933:        {  51, L3, 10, H, 0,-1, KC_F,                           { "f",  "F" } },
                    934:        {  61, L3, 10, H, 0,-1, KC_G,                           { "g",  "G" } },
                    935:        {  71, L3, 10, H, 0,-1, KC_H,                           { "h",  "H" } },
                    936:        {  81, L3, 10, H, 0,-1, KC_J,                           { "j",  "J" } },
                    937:        {  91, L3, 10, H, 0,-1, KC_K,                           { "k",  "K" } },
                    938:        { 101, L3, 10, H, 0,-1, KC_L,                           { "l",  "L" } },
                    939:        { 111, L3, 10, H, 0,-1, KC_semicolon,           { ";",  "+" } },
                    940:        { 121, L3, 10, H, 0,-1, KC_colon,                       { ":",  "*" } },
                    941:        { 131, L3, 10, H, 0,-1, KC_bracketright,        { "]",  "}" } },
                    942: 
1.1.1.6   root      943:        {   2, L4, 24, H, 0,-1, KC_SHIFT,                       { "SHIFT" } },
1.1.1.4   root      944:        {  26, L4, 10, H, 0,-1, KC_Z,                           { "z",  "Z" } },
                    945:        {  36, L4, 10, H, 0,-1, KC_X,                           { "x",  "X" } },
                    946:        {  46, L4, 10, H, 0,-1, KC_C,                           { "c",  "C" } },
                    947:        {  56, L4, 10, H, 0,-1, KC_V,                           { "v",  "V" } },
                    948:        {  66, L4, 10, H, 0,-1, KC_B,                           { "b",  "B" } },
                    949:        {  76, L4, 10, H, 0,-1, KC_N,                           { "n",  "N" } },
                    950:        {  86, L4, 10, H, 0,-1, KC_M,                           { "m",  "M" } },
                    951:        {  96, L4, 10, H, 0,-1, KC_comma,                       { ",",  "<" } },
                    952:        { 106, L4, 10, H, 0,-1, KC_period,                      { ".",  ">" } },
                    953:        { 116, L4, 10, H, 0,-1, KC_slash,                       { "/",  "?" } },
                    954:        { 126, L4, 10, H, 0,-1, KC_underscore,          { " ",  "_" } },
1.1.1.6   root      955:        { 136, L4, 19, H, 0,-1, KC_SHIFT,                       { "SHIFT" } },
1.1.1.4   root      956: 
                    957:        {  21, L5, 10, H, 0, 5, KC_hira,                        { "ひら" } },
                    958:        {  31, L5, 12, H, 0,-1, KC_XF1,                         { "XF1" } },
                    959:        {  43, L5, 13, H, 0,-1, KC_XF2,                         { "XF2" } },
                    960:        {  56, L5, 36, H, 0,-1, KC_space,                       { " " } },
                    961:        {  92, L5, 12, H, 0,-1, KC_XF3,                         { "XF3" } },
                    962:        { 104, L5, 12, H, 0,-1, KC_XF4,                         { "XF4" } },
                    963:        { 116, L5, 12, H, 0,-1, KC_XF5,                         { "XF5" } },
                    964:        { 128, L5, 10, H, 0, 6, KC_zenkaku,                     { "全角" } },
                    965: 
                    966:        // カーソルキー島
                    967:        { 159, L0, 10, H, 0, 0, KC_kana,                        { "かな" } },
                    968:        { 169, L0, 10, H, 0, 1, KC_romaji,                      { "ローマ" } },
                    969:        { 179, L0, 10, H, 0, 2, KC_code,                        { "コード" } },
                    970:        { 159, L1, 10, H, 0,-1, KC_HOME,                        { "HOME" } },
                    971:        { 169, L1, 10, H, 0, 4, KC_INS,                         { "INS" } },
                    972:        { 179, L1, 10, H, 0,-1, KC_DEL,                         { "DEL" } },
                    973:        { 159, L2, 10, H, 0,-1, KC_ROLLUP,                      { "ROLL\n UP" } },
                    974:        { 169, L2, 10, H, 0,-1, KC_ROLLDOWN,            { "ROLL\nDOWN" } },
                    975:        { 179, L2, 10, H, 0,-1, KC_UNDO,                        { "UNDO" } },
                    976:        { 169, L3, 10, H, 0,-1, KC_up,                          { "↑" } },
                    977:        { 159, L3, 10, HT,0,-1, KC_left,                        { "←" } },
                    978:        { 179, L3, 10, HT,0,-1, KC_right,                       { "→" } },
                    979:        { 169, L4, 10, H, 0,-1, KC_down,                        { "↓" } },
                    980:        { 159, L5, 15, H, 0,-1, KC_OPT1,                        { "OPT.1" } },
                    981:        { 174, L5, 15, H, 0,-1, KC_OPT2,                        { "OPT.2" } },
                    982: 
                    983:        // テンキー島
                    984:        { 193, L0, 10, H, 0, 3, KC_CAPS,                        { "CAPS" } },
                    985:        { 203, L0, 10, H, 0,-1, KC_kigou,                       { "記号" } },
                    986:        { 213, L0, 10, H, 0,-1, KC_touroku,                     { "登録" } },
                    987:        { 223, L0, 10, H, 0,-1, KC_HELP,                        { "HELP" } },
                    988:        { 193, L1, 10, H, 0,-1, KC_PAD_CLR,                     { "CLR" } },
                    989:        { 203, L1, 10, H, 0,-1, KC_PAD_divide,          { "/" } },
                    990:        { 213, L1, 10, H, 0,-1, KC_PAD_multiply,        { "*" } },
                    991:        { 223, L1, 10, H, 0,-1, KC_PAD_minus,           { "-" } },
                    992:        { 193, L2, 10, H, 0,-1, KC_PAD_7,                       { "7" } },
                    993:        { 203, L2, 10, H, 0,-1, KC_PAD_8,                       { "8" } },
                    994:        { 213, L2, 10, H, 0,-1, KC_PAD_9,                       { "9" } },
                    995:        { 223, L2, 10, H, 0,-1, KC_PAD_plus,            { "+" } },
                    996:        { 193, L3, 10, H, 0,-1, KC_PAD_4,                       { "4" } },
                    997:        { 203, L3, 10, H, 0,-1, KC_PAD_5,                       { "5" } },
                    998:        { 213, L3, 10, H, 0,-1, KC_PAD_6,                       { "6" } },
                    999:        { 223, L3, 10, H, 0,-1, KC_PAD_equal,           { "=" } },
                   1000:        { 193, L4, 10, H, 0,-1, KC_PAD_1,                       { "1" } },
                   1001:        { 203, L4, 10, H, 0,-1, KC_PAD_2,                       { "2" } },
                   1002:        { 213, L4, 10, H, 0,-1, KC_PAD_3,                       { "3" } },
1.1.1.7   root     1003:        { 223, L4, 10, HT,0,-1, KC_PAD_enter,           { "\xb\xc\xd\xe" } },
1.1.1.4   root     1004:        { 193, L5, 10, H, 0,-1, KC_PAD_0,                       { "0" } },
                   1005:        { 203, L5, 10, H, 0,-1, KC_PAD_comma,           { "," } },
                   1006:        { 213, L5, 10, H, 0,-1, KC_PAD_decimal,         { "." } },
                   1007: 
                   1008:        // Enter だけ矩形でないので別処理するが
                   1009:        // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
                   1010:        { -1, -1, -1, -1, 0,-1, KC_enter,                       { EnterMark } },
                   1011: };
                   1012: 
                   1013: //
1.1.1.6   root     1014: // ソフトウェアキーボード (ウィンドウ)
1.1.1.4   root     1015: //
                   1016: 
                   1017: // コンストラクタ
1.1.1.7   root     1018: WXSoftKeyWindow::WXSoftKeyWindow(wxWindow *parent, vmtype_t vmtype)
                   1019:        : inherited(parent, wxID_ANY, _("Software Keyboard"))
1.1.1.4   root     1020: {
1.1.1.7   root     1021:        wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
                   1022: 
1.1.1.6   root     1023:        if (vmtype == VMTYPE_X68030) {
                   1024:                panel = new WXX68kSoftKeyPanel(this);
                   1025:        } else {
                   1026:                panel = new WXLunaSoftKeyPanel(this);
                   1027:        }
1.1.1.4   root     1028: 
1.1.1.7   root     1029:        topsizer->Add(panel, 0, wxEXPAND);
                   1030: 
                   1031:        SetSizer(topsizer);
1.1.1.4   root     1032:        // 大きさをそれに固定
                   1033:        Fit();
                   1034: }
                   1035: 
                   1036: // デストラクタ
1.1.1.6   root     1037: WXSoftKeyWindow::~WXSoftKeyWindow()
1.1.1.4   root     1038: {
                   1039: }

unix.superglobalmegacorp.com

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