|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.