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