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