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