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