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