Annotation of nono/wx/wxplanemonitor.cpp, revision 1.1.1.3

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;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.