|
|
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:
! 190: // バックバッファのサイズを固定する
1.1.1.4 root 191: wxSize size(u_width * unit, u_height * unit);
1.1.1.13! root 192: SetFixedSize(size);
! 193:
! 194: // コントロールの大きさを変更
1.1 root 195: SetClientSize(size);
1.1.1.6 root 196: SetMinClientSize(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: // 指定のキーを一つ (枠から刻印まで) 描画する。
322: void
1.1.1.11 root 323: WXSoftKeyPanel::DrawKey(const keydata_t& key)
1.1 root 324: {
1.1.1.10 root 325: uint attr = TA::Normal;
326:
1.1 root 327: // 枠
1.1.1.11 root 328: Rect rect(
329: key.x * unit, key.y * unit,
330: key.w * unit + 1, key.h * unit + 1);
331: bitmap.FillRect(palette[0], rect);
332: bitmap.DrawRect(color.Text, rect);
1.1 root 333:
334: // 刻印を選択
335: const char *disp = key.disp[modifier];
336: if (disp == NULL) {
337: disp = key.disp[0];
338: }
339:
1.1.1.10 root 340: // トグルキーのワンショット押しは太字で表示を区別したい
341: const auto it = toggle.find(key.keycode);
342: if (it != toggle.end()) {
343: if (it->second) {
344: attr = TA::Em;
345: }
346: }
347:
1.1 root 348: // Shift_JIS に変換
349: wxString utfstr(disp, wxConvUTF8);
1.1.1.11 root 350: // mb_str() をキャストせずに一度保持しておく必要がある (scan-build 対策)
351: auto mbstr = utfstr.mb_str(conv);
352: const char *sjis = (const char *)mbstr;
1.1.1.4 root 353: // 改行があれば2行に分割
354: char sjis1[8] {};
355: char sjis2[8] {};
356: int sjislen;
357: int row;
358: const char *lf = strchr(sjis, '\n');
359: if (lf == NULL) {
360: // 1行なら、Shift_JIS での文字数は半角換算の文字数と一致する。
361: sjislen = strlen(sjis);
362: row = 1;
363: } else {
364: // 2行に分割。センタリングは1行目の長さだけで調べる。
365: strncpy(sjis1, sjis, lf - sjis);
366: strcpy(sjis2, lf + 1);
367: sjislen = strlen(sjis1);
368: row = 2;
369: }
1.1 root 370:
371: // センタリング
372: int x = key.x + (key.w - sjislen * 2) / 2;
1.1.1.4 root 373: int y = key.y + (key.h - row * 4) / 2;
1.1 root 374:
1.1.1.4 root 375: // LED を描画 (機種によって色々違うので個別クラス側で処理)
376: if (key.led >= 0) {
1.1.1.11 root 377: y += DrawLED(key);
1.1 root 378: }
379:
380: // 文字を描画
1.1.1.11 root 381: x = x * unit + 1;
382: y = y * unit + 1;
1.1.1.4 root 383: if (strcmp(disp, EnterMark) == 0) {
1.1.1.13! root 384: bitmap.DrawBitmap(x, y, *enter_icon, palette);
1.1 root 385: } else {
1.1.1.4 root 386: if (lf == NULL) {
387: // 1行の場合
1.1.1.11 root 388: DrawStringSJIS(x, y, sjis, attr);
1.1.1.4 root 389: } else {
390: // 2行の場合
1.1.1.11 root 391: DrawStringSJIS(x, y, sjis1);
392: y += 4 * unit;
393: DrawStringSJIS(x, y, sjis2);
1.1.1.4 root 394: }
1.1 root 395: }
396: }
397:
398: // エンターキー
399: void
1.1.1.11 root 400: WXSoftKeyPanel::DrawEnterKey()
1.1 root 401: {
1.1.1.11 root 402: // 矩形の内側を背景色で塗りつぶす。
403: bitmap.FillRect(palette[0], enter_top);
404: bitmap.FillRect(palette[0], enter_btm);
405:
406: // 周囲の線分
407: // (A)-(B)
408: bitmap.DrawLineH(color.Text,
409: enter_top.x, enter_top.y, enter_top.GetRight());
410: // (B)-(C)
411: bitmap.DrawLineV(color.Text,
412: enter_top.GetRight(), enter_top.y, enter_btm.GetBottom());
413: // (C)-(D)
414: bitmap.DrawLineH(color.Text,
415: enter_btm.GetRight(), enter_btm.GetBottom(), enter_btm.x);
416: // (D)-(E)
417: bitmap.DrawLineV(color.Text,
418: enter_btm.x, enter_btm.GetBottom(), enter_btm.y);
419: // (E)-(F)
420: bitmap.DrawLineH(color.Text,
421: enter_btm.x, enter_top.GetBottom(), enter_top.x);
422: // (F)-(A)
423: bitmap.DrawLineV(color.Text,
424: enter_top.x, enter_top.GetBottom(), enter_top.y);
1.1 root 425:
426: // エンター記号を描画
1.1.1.13! root 427: bitmap.DrawBitmap(
1.1.1.11 root 428: (enter_top.x + enter_top.GetRight()) / 2 - (4 / 2),
1.1.1.13! root 429: (enter_top.y + enter_btm.GetBottom()) / 2 - (4 / 2),
! 430: *enter_icon, palette);
1.1.1.11 root 431: }
432:
1.1.1.13! root 433: // ブザー表示(キーに相当)を描画
! 434: void
! 435: WXSoftKeyPanel::DrawBuzzer(const keydata_t& key)
! 436: {
! 437: Color fg;
! 438:
! 439: // 枠。キーではないので薄くしておく。
! 440: Rect rect(
! 441: key.x * unit, key.y * unit,
! 442: key.w * unit + 1, key.h * unit + 1);
! 443: bitmap.FillRect(palette[0], rect);
! 444: bitmap.DrawRect(UD_GREY, rect);
! 445:
! 446: // テキスト色は本来呼び出し元の DrawKey() で設定してあるが、
! 447: // ここはキーではないので非発声時の文字色だけ薄くしたい。
! 448: // 発声時はキー押下と同じにする。
! 449: fg = GetTextForeColor();
! 450: if (persistence[key.keycode] == 0) {
! 451: SetTextForeColor(UD_GREY);
! 452: }
1.1.1.11 root 453:
1.1.1.13! root 454: // 刻印 (モディファイヤの影響を受けないと分かっているので常に [0])
! 455: const char *disp = key.disp[0];
! 456: assert(disp);
! 457:
! 458: // センタリング
! 459: int x = key.x + (key.w - strlen(disp) * 2) / 2;
! 460: int y = key.y + (key.h - 4) / 2;
! 461:
! 462: // 文字を描画
! 463: x = x * unit + 1;
! 464: y = y * unit + 1;
! 465: DrawStringSJIS(x, y, disp, TA::Normal);
! 466:
! 467: // 前景色を元に戻す
! 468: SetTextForeColor(fg);
! 469: }
! 470:
! 471: #define B(x) (0b##x)
! 472: #define B2(x) (B(x) >> 8), (B(x) & 0xff)
! 473: #define B3(x) (B(x) >> 16), ((B(x) >> 8) & 0xff), (B(x) & 0xff)
! 474:
! 475: static const uint8 EnterIcon12[] = { // 12x12
! 476: B2(000000000000'0000), // 0
! 477: B2(000000001110'0000), // 1
! 478: B2(000000001010'0000), // 2
! 479: B2(000000001010'0000), // 3
! 480: B2(000000001010'0000), // 4
! 481: B2(001100001010'0000), // 5
! 482: B2(010111110010'0000), // 6
! 483: B2(100000000010'0000), // 7
! 484: B2(010111111100'0000), // 8
! 485: B2(001100000000'0000), // 9
! 486: B2(000000000000'0000), // a
! 487: B2(000000000000'0000), // b
1.1.1.11 root 488: };
1.1.1.13! root 489:
! 490: static const uint8 EnterIcon16[] = { // 16x16
! 491: B2(0000000000111110), // 0
! 492: B2(0000000000100010), // 1
! 493: B2(0000000000100010), // 2
! 494: B2(0000000000100010), // 3
! 495: B2(0000000000100010), // 4
! 496: B2(0000000000100010), // 5
! 497: B2(0000000000100010), // 6
! 498: B2(0000110000100010), // 7
! 499: B2(0001010000100010), // 8
! 500: B2(0010011111000010), // 9
! 501: B2(0100000000000010), // a
! 502: B2(1000000000000010), // b
! 503: B2(0100000000000010), // c
! 504: B2(0010011111111100), // d
! 505: B2(0001010000000000), // e
! 506: B2(0000110000000000), // f
1.1.1.11 root 507: };
1.1 root 508:
1.1.1.13! root 509: static const uint8 EnterIcon24[] = { // 24x24
! 510: B3(00000000'00000001'11111100), // 0
! 511: B3(00000000'00000001'11111100), // 1
! 512: B3(00000000'00000001'10001100), // 2
! 513: B3(00000000'00000001'10001100), // 3
! 514: B3(00000000'00000001'10001100), // 4
! 515: B3(00000000'00000001'10001100), // 5
! 516: B3(00000000'00000001'10001100), // 6
! 517: B3(00000000'00000001'10001100), // 7
! 518: B3(00000000'00000001'10001100), // 8
! 519: B3(00000000'11000001'10001100), // 9
! 520: B3(00000001'11000001'10001100), // 10
! 521: B3(00000011'11000001'10001100), // 11
! 522: B3(00000110'11000001'10001100), // 12
! 523: B3(00001100'11111111'10001100), // 13
! 524: B3(00011000'11111111'10001100), // 14
! 525: B3(00110000'00000000'00001100), // 15
! 526: B3(01100000'00000000'00001100), // 16
! 527: B3(00110000'00000000'00001100), // 17
! 528: B3(00011000'11111111'11111100), // 18
! 529: B3(00001100'11111111'11111000), // 19
! 530: B3(00000110'11000000'00000000), // 20
! 531: B3(00000011'11000000'00000000), // 21
! 532: B3(00000001'11000000'00000000), // 22
! 533: B3(00000000'11000000'00000000), // 23
! 534: };
! 535:
! 536: // アイコンを初期化する。FontChanged() から呼ばれる。
! 537: // ソース先頭のほうにデータの羅列を置きたくないが、
! 538: // 容量不詳の配列の解決が面倒なのでこれだけ下のほうのここに置いてある。
1.1 root 539: void
1.1.1.13! root 540: WXSoftKeyPanel::InitIcon()
1.1 root 541: {
1.1.1.13! root 542: const int width = font_width;
! 543: const int height = font_height;
! 544: const uint8 *icon;
1.1.1.11 root 545:
1.1.1.13! root 546: switch (height) {
1.1.1.11 root 547: case 12:
1.1.1.13! root 548: icon = EnterIcon12;
1.1.1.11 root 549: break;
550: case 16:
1.1.1.13! root 551: icon = EnterIcon16;
! 552: break;
! 553: case 24:
! 554: icon = EnterIcon24;
1.1.1.11 root 555: break;
556: default:
1.1.1.13! root 557: PANIC("Unexpected font_height=%d", height);
1.1 root 558: }
1.1.1.13! root 559:
! 560: enter_icon.reset(new BitmapI1(icon, width * 2, height));
1.1 root 561: }
562:
563: // keycode に対応する keydata を返す
564: const keydata_t&
1.1.1.4 root 565: WXSoftKeyPanel::FindKeydata(uint keycode) const
1.1 root 566: {
1.1.1.6 root 567: for (const auto& key : keydata) {
1.1 root 568: if (key.keycode == keycode) {
569: return key;
570: }
571: }
572: // 見付からないはずはない
1.1.1.11 root 573: PANIC("keycode %d not found", keycode);
1.1 root 574: }
575:
576: // マウス左クリック (Down) イベント
577: void
1.1.1.4 root 578: WXSoftKeyPanel::OnLeftDown(wxMouseEvent& event)
1.1 root 579: {
1.1.1.5 root 580: const wxPoint& pt = event.GetPosition();
1.1.1.4 root 581: const keydata_t *key = GetKeydataFromPoint(pt);
1.1 root 582:
1.1.1.9 root 583: if (key != NULL) {
1.1.1.10 root 584: DoLeftDown(key->keycode);
1.1.1.9 root 585: }
1.1 root 586: }
587:
588: // マウス左クリック (Down) 処理
589: void
1.1.1.10 root 590: WXSoftKeyPanel::DoLeftDown(uint code)
1.1 root 591: {
1.1.1.10 root 592: auto it = toggle.find(code);
593: if (it != toggle.end()) {
594: // トグルキーはここで完結。LeftUp では何もしない。
595: // second のクリアは KeyUp() からコールバックされる OnKeyChanged()
596: // で行っている。
1.1.1.13! root 597: if (keyboard->IsPressed(code)) {
1.1.1.10 root 598: KeyUp(code);
1.1.1.9 root 599: } else {
1.1.1.10 root 600: KeyDown(code);
601: it->second = code;
1.1.1.9 root 602: }
1.1.1.10 root 603: leftdown_key = KC_none;
1.1.1.9 root 604: } else {
1.1.1.10 root 605: // トグルでない通常キーはここで押下して LeftUp のために覚えておく
606: KeyDown(code);
607: leftdown_key = code;
1.1 root 608: }
609: }
610:
611: // マウス左クリック (Up) イベント
612: void
1.1.1.4 root 613: WXSoftKeyPanel::OnLeftUp(wxMouseEvent& event)
1.1 root 614: {
615: // Up 時は、これが起きた地点のキーコードではなく
616: // 直近に LeftDown したキーコードをターゲットにする。
1.1.1.10 root 617: uint code = leftdown_key;
1.1 root 618:
1.1.1.10 root 619: if (code != KC_none) {
620: KeyUp(code);
1.1.1.9 root 621:
1.1.1.10 root 622: // 通常キーが離されたら、トグルキーはすべて開放
623: for (const auto& k : toggle) {
624: auto tcode = k.second;
625: if (tcode) {
626: KeyUp(tcode);
1.1.1.9 root 627: }
628: }
1.1 root 629: }
1.1.1.9 root 630:
1.1.1.10 root 631: leftdown_key = KC_none;
1.1 root 632: }
633:
634: // マウス左ダブルクリックイベント
635: // ダブルクリックという操作に特別何かを割り当ててはいないが、
636: // キーを連打するとその間隔によってはダブルクリックと扱われるため、
637: // 受け取ってここで処理する。
638: //
639: // DClick イベントは LeftDown、LeftUp、LeftDClick、LeftUp の順で
640: // 飛んでくるので、ここでは2回目の押下だけ処理すればよい。というか
641: // 処理自体は LeftDown とまったく同じになるので、イベントテーブルで
642: // 直接 EVT_LEFT_DCLICK => OnLeftDown に割り付けることも出来そうだが
643: // デバッグが紛らわしくなりそうなので独立したイベントとしておく。
644: void
1.1.1.4 root 645: WXSoftKeyPanel::OnLeftDClick(wxMouseEvent& event)
1.1 root 646: {
1.1.1.5 root 647: const wxPoint& pt = event.GetPosition();
1.1.1.4 root 648: const keydata_t *key = GetKeydataFromPoint(pt);
1.1 root 649:
1.1.1.9 root 650: if (key != NULL) {
1.1.1.10 root 651: DoLeftDown(key->keycode);
1.1.1.9 root 652: }
1.1 root 653: }
654:
655: // マウス右クリック (Down) イベント
656: // 長押し開始/解除。
657: // 右クリックのほうは Down だけで Up は使わない。
658: void
1.1.1.4 root 659: WXSoftKeyPanel::OnRightDown(wxMouseEvent& event)
1.1 root 660: {
1.1.1.5 root 661: const wxPoint& pt = event.GetPosition();
1.1.1.4 root 662: const keydata_t *key = GetKeydataFromPoint(pt);
1.1 root 663:
1.1.1.4 root 664: if (key != NULL) {
665: uint code = key->keycode;
1.1.1.13! root 666: if (keyboard->IsPressed(code)) {
1.1 root 667: // 押されていたら開放
1.1.1.10 root 668: KeyUp(code);
1.1 root 669: } else {
670: // 押されてなければ長押し開始
1.1.1.10 root 671: KeyDown(code);
1.1 root 672: }
673: }
674: }
675:
1.1.1.4 root 676: // 座標からキーデータを返す。
677: // キーに当たっていなければ NULL を返す。
678: const keydata_t *
679: WXSoftKeyPanel::GetKeydataFromPoint(const wxPoint& pt) const
1.1 root 680: {
1.1.1.4 root 681: // エンターキーだけ先に別判定
1.1.1.11 root 682: if (enter_top.Contains(pt.x, pt.y) || enter_btm.Contains(pt.x, pt.y)) {
1.1.1.4 root 683: return &FindKeydata(KC_enter);
684: }
1.1 root 685:
1.1.1.6 root 686: for (const auto& key : keydata) {
1.1.1.4 root 687: if (key.x < 0) {
688: continue;
1.1 root 689: }
1.1.1.4 root 690: // 始点と幅の +1/-1 は罫線の分
691: wxRect rect(
692: (key.x * unit) + 1,
693: (key.y * unit) + 1,
694: (key.w * unit) - 1,
695: (key.h * unit) - 1);
696: if (rect.Contains(pt)) {
697: return &key;
1.1 root 698: }
1.1.1.4 root 699: }
700: return NULL;
701: }
702:
1.1.1.6 root 703: // このキーが押された処理
704: void
1.1.1.10 root 705: WXSoftKeyPanel::KeyDown(uint code)
1.1.1.6 root 706: {
1.1.1.9 root 707: // VM に通知 (Keyboard がホストに通知する)
1.1.1.13! root 708: keyboard->MakeKey(code);
1.1.1.6 root 709: }
710:
711: // このキーが放された処理
712: void
1.1.1.10 root 713: WXSoftKeyPanel::KeyUp(uint code)
1.1.1.6 root 714: {
1.1.1.9 root 715: // VM に通知 (Keyboard がホストに通知する)
1.1.1.13! root 716: keyboard->BreakKey(code);
1.1.1.6 root 717: }
718:
719:
1.1.1.4 root 720: //
721: // LUNA ソフトウェアキーボード (パネル)
722: //
723:
724: // コンストラクタ
725: WXLunaSoftKeyPanel::WXLunaSoftKeyPanel(wxWindow *parent)
1.1.1.6 root 726: : inherited(parent, keydata, 226, 54)
1.1.1.4 root 727: {
728: // LUNA では
729: // BS キーの左隣 (0x5c) は円記号ではなくバックスラッシュ。
730: // それを SHIFT したやつ(0x7c) は破線でないパイプ。
731: // そのもう一つ左隣 (0x7e) はオーバーラインではなくチルダ。
1.1.1.11 root 732: gFontManager->SetGlyph5C(true);
733: gFontManager->SetGlyph7E(true);
1.1.1.4 root 734:
1.1.1.9 root 735: // 白黒モデル共通
1.1.1.11 root 736: color.Border = UD_BLACK;
1.1.1.9 root 737: color.LED[0] = UD_RED;
738:
1.1.1.4 root 739: // キートップの濃淡はユニバーサルデザインの推奨色ではないけど
740: // ここは見分けを付けるためではなくただのデザインなので。
741: if (1) {
742: // 白モデル
1.1.1.9 root 743: color.Background = UD_LIGHT_GREY; // 現物新品は何色だったんだろう
1.1.1.11 root 744: color.Text = UD_BLACK;
745: color.Keytop[0][0] = UD_WHITE;
746: color.Keytop[1][0] = Color(200, 200, 203);
1.1.1.4 root 747: } else {
748: // 黒モデル
1.1.1.11 root 749: color.Background = UD_BLACK;
750: color.Text = UD_WHITE;
751: color.Keytop[0][0] = Color(50, 50, 53);
752: color.Keytop[1][0] = UD_BLACK;
1.1.1.4 root 753: }
1.1.1.9 root 754: InitColorKeytop(2);
1.1.1.11 root 755:
756: SetBitmapBGColor(color.Background);
1.1.1.13! root 757: Fill();
1.1.1.4 root 758: }
759:
760: // デストラクタ
761: WXLunaSoftKeyPanel::~WXLunaSoftKeyPanel()
762: {
763: }
764:
765: // LED を描画して刻印描画のための y offset を返す。
766: int
1.1.1.11 root 767: WXLunaSoftKeyPanel::DrawLED(const keydata_t& key)
1.1.1.4 root 768: {
1.1.1.13! root 769: const std::vector<bool>& led = keyboard->GetLED();
1.1.1.11 root 770: Color fg;
771: Color bg;
1.1.1.4 root 772:
773: if (led[key.led]) {
774: // 点灯時は赤、枠は黒
1.1.1.11 root 775: fg = color.Border;
776: bg = color.LED[0];
1.1 root 777: } else {
1.1.1.4 root 778: // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6 root 779: // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
1.1.1.11 root 780: fg = UD_GREY;
781: bg = color.Keytop[key.coltype][0];
1.1 root 782: }
783:
1.1.1.4 root 784: // LED を左肩に描く
1.1.1.11 root 785: Rect rect(key.x * unit + 2, key.y * unit + 2, 4 * unit - 2, 3 * unit - 2);
786: bitmap.FillRect(bg, rect);
787: bitmap.DrawRect(fg, rect);
1.1.1.4 root 788:
789: // そのため文字は少し下げる
790: return +1;
791: }
792:
1.1 root 793: // キーデータ
794: #define H (8) // キーの高さ
795: #define L0 (2) // ファンクションキーの行
796: #define L1 (12) // ESC の行
797: #define L2 (20) // TAB の行
798: #define L3 (28) // CTRL の行
799: #define L4 (36) // SHIFT の行
800: #define L5 (44) // space の行
801: /*static*/ std::vector<keydata_t>
802: WXLunaSoftKeyPanel::keydata {
1.1.1.4 root 803: // +---- キートップの色(1:濃)
804: // | +- 0 以上なら LED 番号
805: // X Y W H C L KeyCode 通常 SHIFT
806: { 2, L0, 15, H, 1,-1, KC_F1, { "PF1" } },
807: { 17, L0, 15, H, 1,-1, KC_F2, { "PF2" } },
808: { 32, L0, 15, H, 1,-1, KC_F3, { "PF3" } },
809: { 47, L0, 15, H, 1,-1, KC_F4, { "PF4" } },
810: { 62, L0, 15, H, 1,-1, KC_F5, { "PF5" } },
811: { 81, L0, 15, H, 1,-1, KC_F6, { "PF6" } },
812: { 96, L0, 15, H, 1,-1, KC_F7, { "PF7" } },
813: { 111, L0, 15, H, 1,-1, KC_F8, { "PF8" } },
814: { 126, L0, 15, H, 1,-1, KC_F9, { "PF9" } },
815: { 141, L0, 15, H, 1,-1, KC_F10, { "PF10" } },
1.1.1.13! root 816: { 210, L0+1, 14, H-2, 1,-1, KC_buzzer, { "Buzzer" } },
1.1.1.4 root 817:
818: { 2, L1, 12, H, 1,-1, KC_ESC, { "ESC" } },
819: { 14, L1, 10, H, 0,-1, KC_1, { "1", "!" } },
820: { 24, L1, 10, H, 0,-1, KC_2, { "2", "\"" } },
821: { 34, L1, 10, H, 0,-1, KC_3, { "3", "#" } },
822: { 44, L1, 10, H, 0,-1, KC_4, { "4", "$" } },
823: { 54, L1, 10, H, 0,-1, KC_5, { "5", "%" } },
824: { 64, L1, 10, H, 0,-1, KC_6, { "6", "&" } },
825: { 74, L1, 10, H, 0,-1, KC_7, { "7", "'" } },
826: { 84, L1, 10, H, 0,-1, KC_8, { "8", "(" } },
827: { 94, L1, 10, H, 0,-1, KC_9, { "9", ")" } },
828: { 104, L1, 10, H, 0,-1, KC_0, { "0", " " } },
829: { 114, L1, 10, H, 0,-1, KC_minus, { "-", "=" } },
830: { 124, L1, 10, H, 0,-1, KC_circum, { "^", "~" } },
831: { 134, L1, 10, H, 0,-1, KC_backslash, { "\\", "|" } },
832: { 144, L1, 12, H, 1,-1, KC_BS, { "BS" } },
833:
834: { 2, L2, 17, H, 1,-1, KC_TAB, { "TAB" } },
835: { 19, L2, 10, H, 0,-1, KC_Q, { "q", "Q" } },
836: { 29, L2, 10, H, 0,-1, KC_W, { "w", "W" } },
837: { 39, L2, 10, H, 0,-1, KC_E, { "e", "E" } },
838: { 49, L2, 10, H, 0,-1, KC_R, { "r", "R" } },
839: { 59, L2, 10, H, 0,-1, KC_T, { "t", "T" } },
840: { 69, L2, 10, H, 0,-1, KC_Y, { "y", "Y" } },
841: { 79, L2, 10, H, 0,-1, KC_U, { "u", "U" } },
842: { 89, L2, 10, H, 0,-1, KC_I, { "i", "I" } },
843: { 99, L2, 10, H, 0,-1, KC_O, { "o", "O" } },
844: { 109, L2, 10, H, 0,-1, KC_P, { "p", "P" } },
845: { 119, L2, 10, H, 0,-1, KC_at, { "@", "`" } },
846: { 129, L2, 10, H, 0,-1, KC_bracketleft, { "[", "{" } },
847:
848: { 2, L3, 20, H, 1,-1, KC_CTRL, { "CTRL" } },
849: { 22, L3, 10, H, 0,-1, KC_A, { "a", "A" } },
850: { 32, L3, 10, H, 0,-1, KC_S, { "s", "S" } },
851: { 42, L3, 10, H, 0,-1, KC_D, { "d", "D" } },
852: { 52, L3, 10, H, 0,-1, KC_F, { "f", "F" } },
853: { 62, L3, 10, H, 0,-1, KC_G, { "g", "G" } },
854: { 72, L3, 10, H, 0,-1, KC_H, { "h", "H" } },
855: { 82, L3, 10, H, 0,-1, KC_J, { "j", "J" } },
856: { 92, L3, 10, H, 0,-1, KC_K, { "k", "K" } },
857: { 102, L3, 10, H, 0,-1, KC_L, { "l", "L" } },
858: { 112, L3, 10, H, 0,-1, KC_semicolon, { ";", "+" } },
859: { 122, L3, 10, H, 0,-1, KC_colon, { ":", "*" } },
860: { 132, L3, 10, H, 0,-1, KC_bracketright, { "]", "}" } },
861:
862: { 2, L4, 25, H, 1,-1, KC_SHIFT_L, { "SHIFT" } },
863: { 27, L4, 10, H, 0,-1, KC_Z, { "z", "Z" } },
864: { 37, L4, 10, H, 0,-1, KC_X, { "x", "X" } },
865: { 47, L4, 10, H, 0,-1, KC_C, { "c", "C" } },
866: { 57, L4, 10, H, 0,-1, KC_V, { "v", "V" } },
867: { 67, L4, 10, H, 0,-1, KC_B, { "b", "B" } },
868: { 77, L4, 10, H, 0,-1, KC_N, { "n", "N" } },
869: { 87, L4, 10, H, 0,-1, KC_M, { "m", "M" } },
870: { 97, L4, 10, H, 0,-1, KC_comma, { ",", "<" } },
871: { 107, L4, 10, H, 0,-1, KC_period, { ".", ">" } },
872: { 117, L4, 10, H, 0,-1, KC_slash, { "/", "?" } },
873: { 127, L4, 10, H, 0,-1, KC_underscore, { " ", "_" } },
874: { 137, L4, 19, H, 1,-1, KC_SHIFT_R, { "SHIFT" } },
875:
876: { 2, L5, 20, H, 1,-1, KC_VALID, { "確定" } },
877: { 22, L5, 10, H, 1,-1, KC_SF, { "前面" } },
878: { 32, L5, 10, H, 1, 1, KC_CAPS, { "CAP" } },
879: { 42, L5, 80, H, 0,-1, KC_space, { " " } },
880: { 122, L5, 10, H, 1, 0, KC_kana, { "かな" } },
881: { 132, L5, 24, H, 1,-1, KC_XFER, { "変換" } },
1.1 root 882:
883: // カーソルキー島
1.1.1.4 root 884: { 160, L1, 10, H, 1,-1, KC_PF11, { "消去" } },
885: { 170, L1, 10, H, 1,-1, KC_PF12, { "呼出" } },
886: { 160, L2, 10, H, 1,-1, KC_PF13, { "文節\n←" } },
887: { 170, L2, 10, H, 1,-1, KC_PF14, { "文節\n→" } },
888: { 160, L3, 20, H, 1,-1, KC_up, { "↑" } },
889: { 160, L4, 10, H, 1,-1, KC_left, { "←" } },
890: { 170, L4, 10, H, 1,-1, KC_right, { "→" } },
891: { 160, L5, 20, H, 1,-1, KC_down, { "↓" } },
1.1 root 892:
893: // テンキー島
1.1.1.4 root 894: { 184, L1, 10, H, 1,-1, KC_DEL, { "DEL" } },
895: { 194, L1, 10, H, 1,-1, KC_PAD_plus, { "+" } },
896: { 204, L1, 10, H, 1,-1, KC_PAD_minus, { "-" } },
897: { 214, L1, 10, H, 1,-1, KC_PAD_multiply, { "*" } },
898:
899: { 184, L2, 10, H, 0,-1, KC_PAD_7, { "7" } },
900: { 194, L2, 10, H, 0,-1, KC_PAD_8, { "8" } },
901: { 204, L2, 10, H, 0,-1, KC_PAD_9, { "9" } },
902: { 214, L2, 10, H, 1,-1, KC_PAD_divide, { "/" } },
903:
904: { 184, L3, 10, H, 0,-1, KC_PAD_4, { "4" } },
905: { 194, L3, 10, H, 0,-1, KC_PAD_5, { "5" } },
906: { 204, L3, 10, H, 0,-1, KC_PAD_6, { "6" } },
907: { 214, L3, 10, H, 1,-1, KC_PAD_equal, { "=" } },
908:
909: { 184, L4, 10, H, 0,-1, KC_PAD_1, { "1" } },
910: { 194, L4, 10, H, 0,-1, KC_PAD_2, { "2" } },
911: { 204, L4, 10, H, 0,-1, KC_PAD_3, { "3" } },
912: { 214, L4, 10, H, 1,-1, KC_PAD_comma, { "," } },
913:
914: { 184, L5, 10, H, 0,-1, KC_PAD_0, { "0" } },
915: { 194, L5, 10, H, 0,-1, KC_PAD_decimal, { "." } },
916: { 204, L5, 20, H, 1,-1, KC_PAD_enter, { EnterMark } },
1.1 root 917:
918: // Enter だけ矩形でないので別処理するが
919: // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
1.1.1.4 root 920: { -1, -1, -1, -1, 1,-1, KC_enter, { EnterMark } },
1.1 root 921: };
922:
923:
924: //
1.1.1.4 root 925: // X68k ソフトウェアキーボード (パネル)
926: //
927:
928: // コンストラクタ
929: WXX68kSoftKeyPanel::WXX68kSoftKeyPanel(wxWindow *parent)
1.1.1.6 root 930: : inherited(parent, keydata, 235, 54)
1.1.1.4 root 931: {
932: // X68k では SRAM 設定に同期させる。
1.1.1.13! root 933: const auto sram = GetSRAMDevice();
! 934: uint8 sw = sram->Peek8(0xed0059);
1.1.1.11 root 935: gFontManager->SetGlyph5C((sw & 0x01));
936: gFontManager->SetGlyph7E((sw & 0x02));
937: gFontManager->SetGlyph7C((sw & 0x04));
1.1.1.4 root 938:
939: // とりあえず黒のみ
1.1.1.11 root 940: color.Background = Color(50, 50, 53);
941: color.Text = UD_WHITE;
942: color.Border = UD_BLACK;
1.1.1.9 root 943: color.LED[0] = UD_RED;
944: color.LED[1] = UD_YELLOW_GREEN;
1.1.1.11 root 945: color.Keytop[0][0] = UD_BLACK;
1.1.1.9 root 946: InitColorKeytop(1);
1.1.1.11 root 947:
948: SetBitmapBGColor(color.Background);
1.1.1.13! root 949: Fill();
1.1.1.4 root 950: }
951:
952: // デストラクタ
953: WXX68kSoftKeyPanel::~WXX68kSoftKeyPanel()
954: {
955: }
956:
957: // LED を描画して刻印描画のための y offset を返す。
958: int
1.1.1.11 root 959: WXX68kSoftKeyPanel::DrawLED(const keydata_t& key)
1.1.1.4 root 960: {
1.1.1.13! root 961: const std::vector<bool>& led = keyboard->GetLED();
1.1.1.11 root 962: Color fg;
963: Color bg;
1.1.1.4 root 964:
965: // 色を選択
966: // idx 刻印 色
967: // ----------------
968: // 0 かな 赤
969: // 1 ローマ 赤
970: // 2 コード 赤
971: // 3 CAPS 赤
972: // 4 INS 赤
973: // 5 ひら 緑
974: // 6 全角 緑
975: if (led[key.led]) {
976: int n = (key.led < 5) ? 0 : 1;
1.1.1.11 root 977: fg = color.LED[n];
978: bg = color.LED[n];
1.1.1.4 root 979: } else {
980: // 消灯時は元のキートップの色で、枠は薄めにしたい
1.1.1.6 root 981: // (枠の色は今の所全モデル共通なので ColorPalette に含めていない)
1.1.1.11 root 982: fg = UD_GREY;
983: bg = color.Keytop[key.coltype][0];
1.1.1.4 root 984: }
985:
986: // LED は中央前方(画面でいうと下)
1.1.1.11 root 987: Rect rect((key.x + 3) * unit, (key.y + key.h - 2) * unit,
988: 4 * unit, 2 * unit);
989: bitmap.FillRect(bg, rect);
990: bitmap.DrawRect(fg, rect);
1.1.1.4 root 991:
992: // そのため文字は少し上げる
993: return -1;
994: }
995:
996: #define LF (L0 + 2) // ファンクションキーは少し低い(横長い)
997: #define HT (H * 2) // 縦2倍角のキー
998: /*static*/ std::vector<keydata_t>
999: WXX68kSoftKeyPanel::keydata {
1000: // +- 0以上なら LED 番号
1001: // X Y W H C L KeyCode 通常 SHIFT
1.1.1.7 root 1002: { 2, L0, 10, H, 0,-1, KC_BREAK, { "\x4\x5\x6\x7" } },
1.1.1.4 root 1003: { 15, L0, 10, H, 0,-1, KC_COPY, { "COPY" } },
1004: { 29, LF, 12, 6, 0,-1, KC_F1, { "F1" } },
1005: { 41, LF, 12, 6, 0,-1, KC_F2, { "F2" } },
1006: { 53, LF, 12, 6, 0,-1, KC_F3, { "F3" } },
1007: { 65, LF, 12, 6, 0,-1, KC_F4, { "F4" } },
1008: { 77, LF, 13, 6, 0,-1, KC_F5, { "F5" } },
1009: { 94, LF, 13, 6, 0,-1, KC_F6, { "F6" } },
1010: { 106, LF, 12, 6, 0,-1, KC_F7, { "F7" } },
1011: { 118, LF, 12, 6, 0,-1, KC_F8, { "F8" } },
1012: { 130, LF, 12, 6, 0,-1, KC_F9, { "F9" } },
1013: { 142, LF, 13, 6, 0,-1, KC_F10, { "F10" } },
1014:
1015: { 2, L1, 10, H, 0,-1, KC_ESC, { "ESC" } },
1016: { 12, L1, 10, H, 0,-1, KC_1, { "1", "!" } },
1017: { 22, L1, 10, H, 0,-1, KC_2, { "2", "\"" } },
1018: { 32, L1, 10, H, 0,-1, KC_3, { "3", "#" } },
1019: { 42, L1, 10, H, 0,-1, KC_4, { "4", "$" } },
1020: { 52, L1, 10, H, 0,-1, KC_5, { "5", "%" } },
1021: { 62, L1, 10, H, 0,-1, KC_6, { "6", "&" } },
1022: { 72, L1, 10, H, 0,-1, KC_7, { "7", "'" } },
1023: { 82, L1, 10, H, 0,-1, KC_8, { "8", "(" } },
1024: { 92, L1, 10, H, 0,-1, KC_9, { "9", ")" } },
1025: { 102, L1, 10, H, 0,-1, KC_0, { "0", " " } },
1026: { 112, L1, 10, H, 0,-1, KC_minus, { "-", "=" } },
1027: { 122, L1, 10, H, 0,-1, KC_circum, { "^", "~" } },
1028: { 132, L1, 10, H, 0,-1, KC_backslash, { "\\", "|" } },
1029: { 142, L1, 13, H, 0,-1, KC_BS, { "BS" } },
1030:
1031: { 2, L2, 16, H, 0,-1, KC_TAB, { "TAB" } },
1032: { 18, L2, 10, H, 0,-1, KC_Q, { "q", "Q" } },
1033: { 28, L2, 10, H, 0,-1, KC_W, { "w", "W" } },
1034: { 38, L2, 10, H, 0,-1, KC_E, { "e", "E" } },
1035: { 48, L2, 10, H, 0,-1, KC_R, { "r", "R" } },
1036: { 58, L2, 10, H, 0,-1, KC_T, { "t", "T" } },
1037: { 68, L2, 10, H, 0,-1, KC_Y, { "y", "Y" } },
1038: { 78, L2, 10, H, 0,-1, KC_U, { "u", "U" } },
1039: { 88, L2, 10, H, 0,-1, KC_I, { "i", "I" } },
1040: { 98, L2, 10, H, 0,-1, KC_O, { "o", "O" } },
1041: { 108, L2, 10, H, 0,-1, KC_P, { "p", "P" } },
1042: { 118, L2, 10, H, 0,-1, KC_at, { "@", "`" } },
1043: { 128, L2, 10, H, 0,-1, KC_bracketleft, { "[", "{" } },
1044:
1045: { 2, L3, 19, H, 0,-1, KC_CTRL, { "CTRL" } },
1046: { 21, L3, 10, H, 0,-1, KC_A, { "a", "A" } },
1047: { 31, L3, 10, H, 0,-1, KC_S, { "s", "S" } },
1048: { 41, L3, 10, H, 0,-1, KC_D, { "d", "D" } },
1049: { 51, L3, 10, H, 0,-1, KC_F, { "f", "F" } },
1050: { 61, L3, 10, H, 0,-1, KC_G, { "g", "G" } },
1051: { 71, L3, 10, H, 0,-1, KC_H, { "h", "H" } },
1052: { 81, L3, 10, H, 0,-1, KC_J, { "j", "J" } },
1053: { 91, L3, 10, H, 0,-1, KC_K, { "k", "K" } },
1054: { 101, L3, 10, H, 0,-1, KC_L, { "l", "L" } },
1055: { 111, L3, 10, H, 0,-1, KC_semicolon, { ";", "+" } },
1056: { 121, L3, 10, H, 0,-1, KC_colon, { ":", "*" } },
1057: { 131, L3, 10, H, 0,-1, KC_bracketright, { "]", "}" } },
1058:
1.1.1.6 root 1059: { 2, L4, 24, H, 0,-1, KC_SHIFT, { "SHIFT" } },
1.1.1.4 root 1060: { 26, L4, 10, H, 0,-1, KC_Z, { "z", "Z" } },
1061: { 36, L4, 10, H, 0,-1, KC_X, { "x", "X" } },
1062: { 46, L4, 10, H, 0,-1, KC_C, { "c", "C" } },
1063: { 56, L4, 10, H, 0,-1, KC_V, { "v", "V" } },
1064: { 66, L4, 10, H, 0,-1, KC_B, { "b", "B" } },
1065: { 76, L4, 10, H, 0,-1, KC_N, { "n", "N" } },
1066: { 86, L4, 10, H, 0,-1, KC_M, { "m", "M" } },
1067: { 96, L4, 10, H, 0,-1, KC_comma, { ",", "<" } },
1068: { 106, L4, 10, H, 0,-1, KC_period, { ".", ">" } },
1069: { 116, L4, 10, H, 0,-1, KC_slash, { "/", "?" } },
1070: { 126, L4, 10, H, 0,-1, KC_underscore, { " ", "_" } },
1.1.1.6 root 1071: { 136, L4, 19, H, 0,-1, KC_SHIFT, { "SHIFT" } },
1.1.1.4 root 1072:
1073: { 21, L5, 10, H, 0, 5, KC_hira, { "ひら" } },
1074: { 31, L5, 12, H, 0,-1, KC_XF1, { "XF1" } },
1075: { 43, L5, 13, H, 0,-1, KC_XF2, { "XF2" } },
1076: { 56, L5, 36, H, 0,-1, KC_space, { " " } },
1077: { 92, L5, 12, H, 0,-1, KC_XF3, { "XF3" } },
1078: { 104, L5, 12, H, 0,-1, KC_XF4, { "XF4" } },
1079: { 116, L5, 12, H, 0,-1, KC_XF5, { "XF5" } },
1080: { 128, L5, 10, H, 0, 6, KC_zenkaku, { "全角" } },
1081:
1082: // カーソルキー島
1083: { 159, L0, 10, H, 0, 0, KC_kana, { "かな" } },
1084: { 169, L0, 10, H, 0, 1, KC_romaji, { "ローマ" } },
1085: { 179, L0, 10, H, 0, 2, KC_code, { "コード" } },
1086: { 159, L1, 10, H, 0,-1, KC_HOME, { "HOME" } },
1087: { 169, L1, 10, H, 0, 4, KC_INS, { "INS" } },
1088: { 179, L1, 10, H, 0,-1, KC_DEL, { "DEL" } },
1089: { 159, L2, 10, H, 0,-1, KC_ROLLUP, { "ROLL\n UP" } },
1090: { 169, L2, 10, H, 0,-1, KC_ROLLDOWN, { "ROLL\nDOWN" } },
1091: { 179, L2, 10, H, 0,-1, KC_UNDO, { "UNDO" } },
1092: { 169, L3, 10, H, 0,-1, KC_up, { "↑" } },
1093: { 159, L3, 10, HT,0,-1, KC_left, { "←" } },
1094: { 179, L3, 10, HT,0,-1, KC_right, { "→" } },
1095: { 169, L4, 10, H, 0,-1, KC_down, { "↓" } },
1096: { 159, L5, 15, H, 0,-1, KC_OPT1, { "OPT.1" } },
1097: { 174, L5, 15, H, 0,-1, KC_OPT2, { "OPT.2" } },
1098:
1099: // テンキー島
1100: { 193, L0, 10, H, 0, 3, KC_CAPS, { "CAPS" } },
1101: { 203, L0, 10, H, 0,-1, KC_kigou, { "記号" } },
1102: { 213, L0, 10, H, 0,-1, KC_touroku, { "登録" } },
1103: { 223, L0, 10, H, 0,-1, KC_HELP, { "HELP" } },
1104: { 193, L1, 10, H, 0,-1, KC_PAD_CLR, { "CLR" } },
1105: { 203, L1, 10, H, 0,-1, KC_PAD_divide, { "/" } },
1106: { 213, L1, 10, H, 0,-1, KC_PAD_multiply, { "*" } },
1107: { 223, L1, 10, H, 0,-1, KC_PAD_minus, { "-" } },
1108: { 193, L2, 10, H, 0,-1, KC_PAD_7, { "7" } },
1109: { 203, L2, 10, H, 0,-1, KC_PAD_8, { "8" } },
1110: { 213, L2, 10, H, 0,-1, KC_PAD_9, { "9" } },
1111: { 223, L2, 10, H, 0,-1, KC_PAD_plus, { "+" } },
1112: { 193, L3, 10, H, 0,-1, KC_PAD_4, { "4" } },
1113: { 203, L3, 10, H, 0,-1, KC_PAD_5, { "5" } },
1114: { 213, L3, 10, H, 0,-1, KC_PAD_6, { "6" } },
1115: { 223, L3, 10, H, 0,-1, KC_PAD_equal, { "=" } },
1116: { 193, L4, 10, H, 0,-1, KC_PAD_1, { "1" } },
1117: { 203, L4, 10, H, 0,-1, KC_PAD_2, { "2" } },
1118: { 213, L4, 10, H, 0,-1, KC_PAD_3, { "3" } },
1.1.1.13! root 1119: { 223, L4, 10, HT,0,-1, KC_PAD_enter, { "\xb\xc\xe\xf" } },
1.1.1.4 root 1120: { 193, L5, 10, H, 0,-1, KC_PAD_0, { "0" } },
1121: { 203, L5, 10, H, 0,-1, KC_PAD_comma, { "," } },
1122: { 213, L5, 10, H, 0,-1, KC_PAD_decimal, { "." } },
1123:
1124: // Enter だけ矩形でないので別処理するが
1125: // この構造体には全部のキー情報が統一的に並んでいるほうがよかろう。
1126: { -1, -1, -1, -1, 0,-1, KC_enter, { EnterMark } },
1127: };
1128:
1129: //
1.1.1.6 root 1130: // ソフトウェアキーボード (ウィンドウ)
1.1.1.4 root 1131: //
1132:
1133: // コンストラクタ
1.1.1.12 root 1134: WXSoftKeyWindow::WXSoftKeyWindow(wxWindow *parent, VMType vmtype)
1.1.1.7 root 1135: : inherited(parent, wxID_ANY, _("Software Keyboard"))
1.1.1.4 root 1136: {
1.1.1.12 root 1137: if (vmtype == VMType::X68030) {
1.1.1.6 root 1138: panel = new WXX68kSoftKeyPanel(this);
1139: } else {
1140: panel = new WXLunaSoftKeyPanel(this);
1141: }
1.1.1.4 root 1142:
1.1.1.11 root 1143: DoSize();
1.1.1.4 root 1144: }
1145:
1146: // デストラクタ
1.1.1.6 root 1147: WXSoftKeyWindow::~WXSoftKeyWindow()
1.1.1.4 root 1148: {
1149: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.