|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // プレーン VRAM モニターウィンドウ
9: //
10:
11: #include "wxplanemonitor.h"
12: #include "wxcolor.h"
13: #include "wxuimessage.h"
1.1.1.2 root 14: #include "bt45x.h"
1.1 root 15: #include "planevram.h"
16: #include "videoctlr.h"
17:
1.1.1.3 root 18: //#define WINDOW_DEBUG 1
19:
20: #if defined(WINDOW_DEBUG)
21: #define DPRINTF(fmt...) printf(fmt)
22: #else
23: #define DPRINTF(fmt...) /**/
24: #endif
25:
1.1 root 26: enum {
27: ID_PLANE0 = IDGROUP_PLANEVRAM,
28: ID_PLANE1,
29: ID_PLANE2,
30: ID_PLANE3,
31: ID_PLANE4,
32: ID_PLANE5,
33: ID_PLANE6,
34: ID_PLANE7,
35: ID_PALETTE,
36: ID_SCALE,
37:
38: ID_local_end, // 最後に置く (チェック用)
39: };
40: static_assert(ID_local_end - 1 <= (int)IDGROUP_PLANEVRAM_END, "ID exceeded");
41:
42: #define ID_PLANE(id) (ID_PLANE0 + (id))
43:
44: //
45: // プレーン VRAM ビットマップ
46: //
47:
1.1.1.2 root 48: // イベントテーブル
49: wxBEGIN_EVENT_TABLE(WXPlaneVRAMBitmapPanel, inherited)
50: EVT_MOUSE_EVENTS(WXPlaneVRAMBitmapPanel::OnMouse)
51: wxEND_EVENT_TABLE()
52:
1.1 root 53: // コンストラクタ
54: WXPlaneVRAMBitmapPanel::WXPlaneVRAMBitmapPanel(wxWindow *parent)
55: : inherited(parent)
56: {
1.1.1.2 root 57: // デバイスを取得
58: planevram = GetPlaneVRAMDevice();
59: // どちらか一方は NULL のはず
60: bt45x = gMainApp.FindObject<BT45xDevice>(OBJ_BT45x);
61: videoctlr = gMainApp.FindObject<VideoCtlrDevice>(OBJ_VIDEOCTLR);
62:
63: plane_width = planevram->GetComposite().GetWidth();
64: plane_height = planevram->GetComposite().GetHeight();
1.1 root 65:
66: // まず等倍でセット
67: scale = 1;
68: SetScale(1);
69:
1.1.1.2 root 70: cursor = wxDefaultPosition;
71:
1.1 root 72: // VM からの通知を受け取る
73: WXUIMessage::Connect(UIMessage::PALETTE, this,
74: wxCommandEventHandler(WXPlaneVRAMBitmapPanel::OnPaletteChanged));
75: }
76:
77: // デストラクタ
78: WXPlaneVRAMBitmapPanel::~WXPlaneVRAMBitmapPanel()
79: {
1.1.1.2 root 80: WXUIMessage::Disconnect(UIMessage::PALETTE, this,
1.1 root 81: wxCommandEventHandler(WXPlaneVRAMBitmapPanel::OnPaletteChanged));
82: }
83:
84: // XXX 実際にはこの辺かどこかで更新チェックをしないといけない。
85: // 今は表示領域を毎回描画しているので無駄。
86:
87: // ビットマッププレーンの内容を描画する
88: void
89: WXPlaneVRAMBitmapPanel::Draw()
90: {
91: assert(view.GetRight() < virtual_width);
92: assert(view.GetBottom() < virtual_height);
93:
1.1.1.2 root 94: const BitmapI8& src = planevram->GetComposite();
1.1 root 95:
96: if (scale > 1) {
97: Rect dr(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
98: bitmap.DrawScale(dr, src, &pal[0], view.x, scale, 1, view.y, scale, 1);
99: } else {
100: bitmap.DrawBitmap(0, 0, src, &pal[0], view);
101: }
102: }
103:
104: // プレーン選択変更
105: void
106: WXPlaneVRAMBitmapPanel::EnablePlane(int plane, bool value)
107: {
108: if (value) {
109: planemask |= 1U << plane;
110: } else {
111: planemask &= ~(1U << plane);
112: }
113:
114: // パレット生成
115: GenPalette();
116: }
117:
118: // パレット適用変更
119: void
120: WXPlaneVRAMBitmapPanel::EnablePalette(bool value)
121: {
122: apply_palette = value;
123:
124: // パレット生成
125: GenPalette();
126: }
127:
128: // VM からのパレット変更通知
129: void
130: WXPlaneVRAMBitmapPanel::OnPaletteChanged(wxCommandEvent& event)
131: {
132: // パレット生成
133: GenPalette();
134: }
135:
136: // パレット生成
137: void
138: WXPlaneVRAMBitmapPanel::GenPalette()
139: {
140: if (apply_palette) {
141: // パレットを適用する場合
1.1.1.4 ! root 142: // (雑に X680x0/LUNA 対応)
! 143: const std::vector<ColorXBGR> *vmpal;
1.1.1.2 root 144: if (videoctlr) {
1.1.1.4 ! root 145: vmpal = &videoctlr->GetHostPalette();
1.1 root 146: } else {
1.1.1.4 ! root 147: vmpal = &bt45x->GetHostPalette();
1.1 root 148: }
1.1.1.4 ! root 149: int vmpal_size = vmpal->size();
! 150: const Color bg = (*vmpal)[0].ToColor();
! 151: int d = 0;
! 152: int s;
! 153: for (; d < pal.size(); d++) {
! 154: s = d % vmpal_size;
! 155: if ((s & planemask)) {
! 156: pal[d] = (*vmpal)[s].ToColor();
1.1 root 157: } else {
1.1.1.4 ! root 158: pal[d] = bg;
1.1 root 159: }
160: }
161: } else {
162: // パレットを適用しない場合
163: for (int i = 0; i < pal.size(); i++) {
164: if ((i & planemask)) {
165: pal[i] = Color(255, 255, 255);
166: } else {
167: pal[i] = Color(0, 0, 0);
168: }
169: }
170: }
171: }
172:
173: // 倍率を設定
174: void
175: WXPlaneVRAMBitmapPanel::SetScale(int scale_)
176: {
177: int before = scale;
178:
179: scale = scale_;
180:
181: // 仮想画面の大きさを計算
182: virtual_width = plane_width * scale;
183: virtual_height = plane_height * scale;
184:
185: // ビューのスケール変換は前後のスケールがいるのでここでやる
186: view.x = view.x * scale / before;
187: view.y = view.y * scale / before;
188: view.w = view.w * scale / before;
189: view.h = view.h * scale / before;
190:
191: SetMaxClientSize(wxSize(virtual_width, virtual_height));
192: }
193:
194: // スクロール位置変更通知
195: void
196: WXPlaneVRAMBitmapPanel::OnScroll(wxScrollEvent& event)
197: {
198: int orient = event.GetOrientation();
199: int pos = event.GetPosition();
200:
201: if (orient == wxHORIZONTAL) {
202: view.x = pos;
203: } else {
204: view.y = pos;
205: }
206: }
207:
1.1.1.2 root 208: // マウスイベント
209: void
210: WXPlaneVRAMBitmapPanel::OnMouse(wxMouseEvent& event)
211: {
212: auto window = dynamic_cast<WXPlaneVRAMWindow*>(GetGrandParent());
213: assert(window);
214:
215: // pt はこのパネル左上からの位置
216: const wxPoint& pt = event.GetPosition();
217:
218: // pt がパネル内の座標なのに Leaving() になることがある。
219: // pt がパネル外の座標なのに Leaving() にならないことがある。
220: if (event.Leaving() == false && GetClientRect().Contains(pt)) {
221: // cursor は仮想画面上の座標
222: cursor.x = (view.x + pt.x) / scale;
223: cursor.y = (view.y + pt.y) / scale;
224: assertmsg(cursor.x < plane_width, "cursor.x=%d", cursor.x);
225: assertmsg(cursor.y < plane_height, "cursor.y=%d", cursor.y);
226: } else {
227: cursor = wxDefaultPosition;
228: }
229: }
230:
1.1 root 231:
232: //
233: // プレーン VRAM パネル
234: //
235:
1.1.1.2 root 236: // +------------------------+------------------+
237: // | WXPlaneVRAMBitmapPanel | WXScrollBar(V) |
238: // | VRAM 表示パネル | 縦スクロールバー |
239: // +------------------------+------------------+
240: // | WXScrollBar(H) | WXBitmapPanel |
241: // | 横スクロールバー | 空き地 |
242: // +------------------------+------------------+
243:
1.1 root 244: // イベントテーブル
245: wxBEGIN_EVENT_TABLE(WXPlaneVRAMPanel, inherited)
246: EVT_SIZE(WXPlaneVRAMPanel::OnSize)
247: wxEND_EVENT_TABLE()
248:
249: // コンストラクタ
250: WXPlaneVRAMPanel::WXPlaneVRAMPanel(wxWindow *parent)
251: : inherited(parent)
252: {
253: // 表示パネル
254: viewctl = new WXPlaneVRAMBitmapPanel(this);
255:
256: // スクロールバーを自分で持つ (配置は Layout() で行う)
257: vscroll = new WXScrollBar(this, wxID_ANY, wxSB_VERTICAL);
258: hscroll = new WXScrollBar(this, wxID_ANY, wxSB_HORIZONTAL);
259:
260: // 右下の空き地
261: corner = new WXBitmapPanel(this);
262:
263: // Sizer 使わず自前でレイアウトする。
264: SetAutoLayout(true);
265:
266: // スクロールバーからの通知イベントは表示パネルへ回す
267: vscroll->Connect(NONO_EVT_SCROLL,
268: wxScrollEventHandler(WXPlaneVRAMBitmapPanel::OnScroll), NULL, viewctl);
269: hscroll->Connect(NONO_EVT_SCROLL,
270: wxScrollEventHandler(WXPlaneVRAMBitmapPanel::OnScroll), NULL, viewctl);
1.1.1.3 root 271:
272: DPRINTF("Panel.ctor end\n");
1.1 root 273: }
274:
275: // デストラクタ
276: WXPlaneVRAMPanel::~WXPlaneVRAMPanel()
277: {
278: }
279:
280: bool
281: WXPlaneVRAMPanel::Layout()
282: {
1.1.1.3 root 283: DPRINTF("Panel.Layout\n");
1.1 root 284: if (inherited::Layout() == false) {
285: return false;
286: }
287:
288: const wxSize size = GetClientSize();
1.1.1.3 root 289: DPRINTF("Panel.Layout inherited, client=(%d,%d)\n", size.x, size.y);
290: wxSize vscr = vscroll->GetClientSize();
291: wxSize hscr = hscroll->GetClientSize();
292: DPRINTF("Panel.Layout vscr=(%d,%d) hscr=(%d,%d)\n",
293: vscr.x, vscr.y, hscr.x, hscr.y);
294: // 主方向(スクロール方向) の最小サイズ
295: int vmin = vscroll->GetMinLength();
296: int hmin = hscroll->GetMinLength();
297:
298: // 最小サイズはスクロールバーの大きさで制約がかかる。
299: // (VRAM パネルなので実際はもっと広くてもいいかも知れない)
300: SetMinClientSize(wxSize(hmin + vscr.x, vmin + hscr.y));
301: SetMaxClientSize(wxSize(viewctl->virtual_width + vscr.x,
302: viewctl->virtual_height + hscr.y));
303:
304: #if defined(WINDOW_DEBUG)
305: const wxSize& min = GetMinClientSize();
306: const wxSize& max = GetMaxClientSize();
307: const wxSize& cli = GetClientSize();
308: printf("Panel.Layout min=(%d,%d) max=(%d,%d) client=(%d,%d)\n",
309: min.x, min.y, max.x, max.y, cli.x, cli.y);
310: #endif
311:
312: // コントロールを配置
313: int view_width = size.x - vscr.x;
314: int view_height = size.y - hscr.y;
315: DPRINTF("Panel.Layout view=(%d,%d)\n", view_width, view_height);
316: // 最低でも 1px ないと GTK とかに怒られる
317: if (view_width < 1) {
318: view_width = 1;
319: }
320: if (view_height < 1) {
321: view_height = 1;
322: }
323:
1.1 root 324: viewctl->SetSize(0, 0, view_width, view_height);
1.1.1.3 root 325: vscroll->SetSize(view_width, 0, vscr.x, view_height);
326: hscroll->SetSize(0, view_height, view_width, hscr.y);
327: corner->SetSize(view_width, view_height, vscr.x, hscr.y);
1.1 root 328:
329: // XXX 内部のコントロールのサイズが確定してからでないと DoSize() できない
330: DoSize(size);
1.1.1.3 root 331: DPRINTF("Panel.Layout done\n");
1.1 root 332:
333: return true;
334: }
335:
1.1.1.3 root 336: // フォントサイズ変更
337: void
338: WXPlaneVRAMPanel::FontChanged()
339: {
340: // このパネル自体はフォントを出力しないが
341: // フォントサイズ変更に反応する必要があるため、用意している。
342:
343: // 自身がフォントを使わないので呼ばなくてもいいが、お作法として。
344: inherited::FontChanged();
345: DPRINTF("Panel.FontChanged %d\n", font_height);
346:
347: // SubWindow はパネルの FontChanged() までは呼んでくれるけど、
348: // パネルが子を持ってるケースは自力で伝搬させるとかする必要がある。
349: hscroll->FontChanged();
350: vscroll->FontChanged();
351:
352: // レイアウト変更も手動で指示。
353: Layout();
354: DPRINTF("Panel.FontChanged end\n");
355: }
356:
1.1 root 357: // サイズ変更イベント
358: void
359: WXPlaneVRAMPanel::OnSize(wxSizeEvent& event)
360: {
361: // Mac ではウィンドウ作成時に 0 以下の値が来ることがある。
362: // GTK では 1 で来ることがある。
363: wxSize size = event.GetSize();
1.1.1.3 root 364: DPRINTF("Panel.OnSize (%d,%d)\n", size.x, size.y);
1.1 root 365: if (size.x <= 1 || size.y <= 1) {
366: return;
367: }
368:
369: // Layout() を呼ぶために必要
370: event.Skip();
371:
372: // XXX レイアウトが終わった後でないと DoSize() できない
373: // DoSize(size);
374: }
375:
376: // サイズ変更処理。パネルサイズと倍率が変わったら呼ぶこと。
377: // 倍率が変わった場合もスクロールバーの再設定とかがあるため。
378: void
379: WXPlaneVRAMPanel::DoSize(wxSize size)
380: {
381: wxSize viewsize = viewctl->GetClientSize();
1.1.1.3 root 382: DPRINTF("Panel.DoSize: view=(%d,%d)\n", viewsize.x, viewsize.y);
1.1 root 383: int virtual_width = viewctl->virtual_width;
384: int virtual_height = viewctl->virtual_height;
385: Rect& view = viewctl->view;
386:
387: // スクロールバーが右端まで行っている場合は右を固定したように見せる。
388: // ただし全体が見えている場合は除く。
389:
390: if (view.x > 0 &&
391: (view.x + view.w == virtual_width ||
392: view.x + viewsize.x >= virtual_width))
393: {
394: view.x = virtual_width - viewsize.x;
395: if (view.x < 0) {
396: view.x = 0;
397: }
398: }
399: view.w = viewsize.x;
400:
401: // 下端も同様
402: if (view.y > 0 &&
403: (view.y + view.h >= virtual_height ||
404: view.y + size.y >= virtual_height))
405: {
406: view.y = virtual_height - viewsize.y;
407: if (view.y < 0) {
408: view.y = 0;
409: }
410: }
411: view.h = viewsize.y;
412:
413: // スクロールバー(横)を再設定
414: assert(hscroll);
415: int hpos = view.x;
416: int hthumbsize = view.w;
417: int hrange = virtual_width;
418: int hpagesize = view.w;
419: hscroll->SetScrollParam(hpos, hthumbsize, hrange, hpagesize);
420:
421: // スクロールバー(縦)を再設定
422: assert(vscroll);
423: int vpos = view.y;
424: int vthumbsize = view.h;
425: int vrange = virtual_height;
426: int vpagesize = view.h;
427: vscroll->SetScrollParam(vpos, vthumbsize, vrange, vpagesize);
428: }
429:
430: // プレーン選択変更
431: void
432: WXPlaneVRAMPanel::EnablePlane(int plane, bool value)
433: {
434: viewctl->EnablePlane(plane, value);
435: }
436:
437: // パレット適用変更
438: void
439: WXPlaneVRAMPanel::EnablePalette(bool value)
440: {
441: viewctl->EnablePalette(value);
442: }
443:
444: // 倍率を設定
445: void
446: WXPlaneVRAMPanel::SetScale(int scale_)
447: {
448: viewctl->SetScale(scale_);
449:
450: int vscr_width = vscroll->GetClientSize().x;
451: int hscr_height = hscroll->GetClientSize().y;
452: SetMaxClientSize(wxSize(viewctl->virtual_width + vscr_width,
453: viewctl->virtual_height + hscr_height));
454:
455: DoSize(GetSize());
456: }
457:
458:
459: //
460: // プレーン VRAM ウィンドウ
461: //
462:
1.1.1.2 root 463: // ↓+-----------------------------+
464: // | wx コントロール用パネル |
465: // +-----------------------------+
466: // | WXTextScreen *statuspanel | ← 情報欄
467: // +-----------------------------+
468: // | WXPlaneVRAMPanel *viewpanel | ← ビットマップ (スクロールバー込み)
469: // +-----------------------------+
470:
1.1 root 471: // イベントテーブル
472: wxBEGIN_EVENT_TABLE(WXPlaneVRAMWindow, inherited)
473: EVT_COMMAND_RANGE(ID_PLANE0, ID_PLANE7, wxEVT_CHECKBOX,
474: WXPlaneVRAMWindow::OnPlane)
475: EVT_CHECKBOX(ID_PALETTE, WXPlaneVRAMWindow::OnApplyPalette)
476: EVT_CHOICE(ID_SCALE, WXPlaneVRAMWindow::OnScale)
1.1.1.2 root 477: EVT_TIMER(wxID_ANY, WXPlaneVRAMWindow::OnTimer)
1.1 root 478: wxEND_EVENT_TABLE()
479:
480: // コンストラクタ
481: WXPlaneVRAMWindow::WXPlaneVRAMWindow(wxWindow *parent, const wxString& name)
482: : inherited(parent, wxID_ANY, name,
483: inherited::DEFAULT_STYLE | wxRESIZE_BORDER)
484: {
1.1.1.2 root 485: // デバイスを取得
486: planevram = GetPlaneVRAMDevice();
487:
488: int nplane = planevram->GetPlaneCount();
489:
1.1 root 490: auto *topsizer = new wxBoxSizer(wxVERTICAL);
491:
492: // 上にコントロールパネル(のまず下敷き)
1.1.1.2 root 493: ctrlpanel = new wxPanel(this);
1.1 root 494: topsizer->Add(ctrlpanel, 0, wxEXPAND);
495:
496: // コントロールパネル用の横 Sizer
497: auto *ctrlbox = new wxBoxSizer(wxHORIZONTAL);
498:
1.1.1.2 root 499: // プレーン選択チェックボックス
500: auto *csbox = new wxStaticBoxSizer(wxHORIZONTAL, ctrlpanel,
501: _("Planes to display"));
502: // GTK3 標準のレンダリングだとコントロールの周りの空きがなさすぎて
503: // 特にスタティックボックスは読みづらいので自力で少し空ける。どうして…。
504: ctrlbox->Add(csbox, 0, wxALIGN_CENTER | wxALL, 3);
505: // X68030 なら 4プレーン。
506: // LUNA で 1bpp なら 4プレーン (上位3つは Disabled)、
507: // LUNA で 4bpp なら 4プレーン、
508: // LUNA で 8bpp なら 8プレーン。
509: int nplane4 = (nplane == 1) ? 4 : nplane;
510: for (int i = 0; i < nplane4; i++) {
511: auto *ctrl = new wxCheckBox(ctrlpanel, ID_PLANE(i),
512: string_format("%d", i));
513: planesw.push_back(ctrl);
514: }
515: // 降順に並べる
516: for (int i = nplane4 - 1; i >= 0; i--) {
517: csbox->Add(planesw[i]);
1.1 root 518: }
519:
520: // パレット合成チェックボックス
521: applysw = new wxCheckBox(ctrlpanel, ID_PALETTE, _("Apply palette"));
1.1.1.2 root 522: ctrlbox->Add(applysw, 0, wxALIGN_CENTER | wxALL, 3);
1.1 root 523:
524: // セパレータを出したいのだが…
1.1.1.2 root 525: ctrlbox->Add(new wxStaticText(ctrlpanel, wxID_ANY, "|"), 0,
526: wxALIGN_CENTER | wxALL, 3);
1.1 root 527:
528: // 倍率
529: wxString scale_choice[] = {
530: "x1",
531: "x2",
532: "x4",
533: };
534: scalesw = new wxChoice(ctrlpanel, ID_SCALE,
535: wxDefaultPosition, wxDefaultSize,
536: countof(scale_choice), scale_choice);
1.1.1.2 root 537: ctrlbox->Add(scalesw, 0, wxALIGN_CENTER | wxALL, 3);
1.1 root 538:
539: // sizer と下敷きパネルを紐付ける
540: ctrlpanel->SetSizer(ctrlbox);
541: ctrlbox->SetSizeHints(ctrlpanel);
542:
1.1.1.3 root 543: // 情報パネルは大きさを固定
544: statuspanel = new WXTextScreen(this, nnSize(60, nplane));
545: statuspanel->SetMinClientSize(statuspanel->GetDesiredSize());
1.1.1.2 root 546: topsizer->Add(statuspanel, 0, wxEXPAND);
547:
1.1 root 548: viewpanel = new WXPlaneVRAMPanel(this);
549: topsizer->Add(viewpanel, 1, wxEXPAND);
550:
551: SetSizer(topsizer);
552:
1.1.1.3 root 553: FontChanged();
1.1 root 554:
1.1.1.2 root 555: // 1bpp ならプレーン選択はすべて無効、それ以外はすべて有効。
556: if (nplane == 1) {
1.1 root 557: for (int i = 0; i < planesw.size(); i++) {
558: planesw[i]->Enable(false);
559: }
560: }
561:
562: // 初期値をコントロールにセットする
563: if (sticky_used) {
564: // 前回の値があればそれを使う。
565: for (int i = 0; i < planesw.size(); i++) {
566: planesw[i]->SetValue(sticky_plane[i]);
567: }
568: applysw->SetValue(sticky_apply);
569: scalesw->SetSelection(sticky_scale);
570: } else {
1.1.1.2 root 571: if (nplane == 1) {
1.1 root 572: // 初回 1bpp なら #0 プレーンのみオン。
573: for (int i = 0; i < planesw.size(); i++) {
574: planesw[i]->SetValue((i == 0));
575: }
576: applysw->SetValue(true);
577: } else {
578: // 初回 4bpp なら全プレーンオン。
579: for (int i = 0; i < planesw.size(); i++) {
580: planesw[i]->SetValue(true);
581: }
582: applysw->SetValue(true);
583: }
584: scalesw->SetSelection(0);
585: }
586:
587: // SetValue() ではイベントが飛ばないので、
588: // 直接呼び出してイベントが来たことにする。うーん…。
589: for (int i = 0; i < planesw.size(); i++) {
590: DoPlane(i, planesw[i]->IsChecked());
591: }
592: DoApplyPalette(applysw->IsChecked());
593: DoScale(scalesw->GetSelection());
1.1.1.2 root 594:
595: // 更新タイマーはモニターパネル同様の 30Hz にしておく。
596: timer.SetOwner(this);
597: timer.Start(33);
1.1.1.3 root 598:
599: DPRINTF("Window.ctor end\n");
1.1 root 600: }
601:
602: // デストラクタ
603: WXPlaneVRAMWindow::~WXPlaneVRAMWindow()
604: {
605: }
606:
607: void
608: WXPlaneVRAMWindow::FontChanged()
609: {
1.1.1.3 root 610: DPRINTF("Window.FontChanged\n");
611: inherited::FontChanged();
612: DPRINTF("Window.FontChanged inherited\n");
613:
614: // 子コントロールのサイズが変わったのでウィンドウサイズを再計算。
615: // 最小サイズは上コントロール部と情報パネルの横幅のうち大きい方が基準。
616: wxSize minsize = ctrlpanel->GetMinClientSize();
617: const wxSize& statsize = statuspanel->GetDesiredSize();
618: const wxSize& statmin __unused = statuspanel->GetMinClientSize();
619: const wxSize& viewmin __unused = viewpanel->GetMinClientSize();
620: DPRINTF("Window.FontChanged ctrl.min=(%d,%d)\n", minsize.x, minsize.y);
621: DPRINTF("Window.FontChanged stat.min=(%d,%d) des=(%d,%d)\n",
622: statmin.x, statmin.y, statsize.x, statsize.y);
623: DPRINTF("Window.FontChanged view.min=(%d,%d)\n", viewmin.x, viewmin.y);
624:
625: minsize.x = std::max(minsize.x, statsize.x);
626: minsize.y += statsize.y;
627: minsize.y += viewmin.y;
628: DPRINTF("Window.FontChanged SetMin=(%d,%d)\n", minsize.x, minsize.y);
629: SetMinClientSize(minsize);
630: SetClientSize(minsize);
631: Layout();
632:
633: DPRINTF("Window.FontChanged end\n");
1.1 root 634: }
635:
636: // プレーン選択のチェックボックスイベント
637: void
638: WXPlaneVRAMWindow::OnPlane(wxCommandEvent& event)
639: {
640: int plane = event.GetId() - ID_PLANE0;
641: bool value = event.IsChecked();
642:
643: DoPlane(plane, value);
644: }
645:
646: // プレーン選択 ON/OFF 処理
647: void
648: WXPlaneVRAMWindow::DoPlane(int plane, bool value)
649: {
650: // コントロールに指示
651: viewpanel->EnablePlane(plane, value);
652:
653: // 値を保存
654: sticky_plane[plane] = value;
655: sticky_used = true;
656: }
657:
658: // パレット合成のチェックボックスイベント
659: void
660: WXPlaneVRAMWindow::OnApplyPalette(wxCommandEvent& event)
661: {
662: bool value = event.IsChecked();
663:
664: DoApplyPalette(value);
665: }
666:
667: // パレット合成 ON/OFF 処理
668: void
669: WXPlaneVRAMWindow::DoApplyPalette(bool value)
670: {
671: // コントロールに指示
672: viewpanel->EnablePalette(value);
673:
674: // 値を保存
675: sticky_apply = value;
676: sticky_used = true;
677: }
678:
679: // 倍率変更イベント
680: void
681: WXPlaneVRAMWindow::OnScale(wxCommandEvent& event)
682: {
683: int scale_index = event.GetSelection();
684:
685: DoScale(scale_index);
686: }
687:
688: // 倍率変更処理
689: void
690: WXPlaneVRAMWindow::DoScale(int scale_index)
691: {
692: viewpanel->SetScale(1 << scale_index);
693:
694: // 最大サイズは表示部の最大サイズから
695: wxSize maxsize = viewpanel->GetMaxClientSize();
696: maxsize.y += ctrlpanel->GetMinClientSize().y;
1.1.1.2 root 697: maxsize.y += statuspanel->GetMinClientSize().y;
1.1 root 698: SetMaxClientSize(maxsize);
699:
700: // 保存しておくのはインデックスのほう
701: sticky_scale = scale_index;
702: }
703:
1.1.1.2 root 704: // タイマーイベント
705: void
706: WXPlaneVRAMWindow::OnTimer(wxTimerEvent& event)
707: {
708: viewpanel->Refresh();
709:
710: // この位置の情報で screen を更新
711: TextScreen& screen = statuspanel->GetScreen();
712: const wxPoint& cursor = viewpanel->GetCursor();
713:
714: // UpdateInfo() は cursor.x が範囲外の時の描画も行っている。
715: planevram->UpdateInfo(screen, cursor.x, cursor.y);
716: statuspanel->Refresh();
717: }
718:
1.1 root 719: // static 変数
1.1.1.2 root 720: std::array<bool, WXPlaneVRAMWindow::MAX_PLANES> WXPlaneVRAMWindow::sticky_plane;
1.1 root 721: bool WXPlaneVRAMWindow::sticky_apply;
722: int WXPlaneVRAMWindow::sticky_scale;
723: bool WXPlaneVRAMWindow::sticky_used;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.