|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2019 [email protected] ! 4: // ! 5: ! 6: #include "wxheader.h" ! 7: #include "wxvideomonitor.h" ! 8: #include "bitmap.h" ! 9: ! 10: // ! 11: // LUNA ビットマップパネル ! 12: // ! 13: ! 14: // イベントテーブル ! 15: wxBEGIN_EVENT_TABLE(WXLunaBitmapPanel, inherited) ! 16: EVT_PAINT(WXLunaBitmapPanel::OnPaint) ! 17: EVT_SIZE(WXLunaBitmapPanel::OnSize) ! 18: EVT_SCROLLWIN(WXLunaBitmapPanel::OnScrollWin) ! 19: wxEND_EVENT_TABLE() ! 20: ! 21: // コンストラクタ ! 22: WXLunaBitmapPanel::WXLunaBitmapPanel(wxWindow *parent) ! 23: : inherited(parent, wxID_ANY, wxDefaultPosition, ! 24: wxSize(512, 384)) // 初期値は適当 ! 25: { ! 26: src = gBitmap->GetBuf(); ! 27: ! 28: // 仮想キャンバスサイズを設定 ! 29: SetVirtualSize(virtual_width, virtual_height); ! 30: // スクロールバーを設定 ! 31: SetScrollRate(width_per_unit, height_per_unit); ! 32: SetScrollbars(width_per_unit, height_per_unit, ! 33: virtual_width / width_per_unit, ! 34: virtual_height / height_per_unit); ! 35: } ! 36: ! 37: // デストラクタ ! 38: WXLunaBitmapPanel::~WXLunaBitmapPanel() ! 39: { ! 40: if (bmpbuf) { ! 41: delete bmpbuf; ! 42: } ! 43: } ! 44: ! 45: // サイズ変更イベント ! 46: void ! 47: WXLunaBitmapPanel::OnSize(wxSizeEvent& event) ! 48: { ! 49: // Mac ではウィンドウ作成時に 0 以下の値が来ることがある ! 50: // GTK では 1 で来ることがある ! 51: wxSize size = event.GetSize(); ! 52: if (size.x <= 1 || size.y <= 1) { ! 53: return; ! 54: } ! 55: ! 56: view_width = size.x; ! 57: view_height = size.y; ! 58: ! 59: // BMP バッファを持っていれば一旦解放 ! 60: if (bmpbuf) { ! 61: delete bmpbuf; ! 62: bmpbuf = NULL; ! 63: } ! 64: ! 65: // BMP バッファ作成 ! 66: // 正しく描かれなかった時に分かりやすいよう初期値は濃いグレーにしておく ! 67: bmpbuf = new uint8 [view_width * view_height * 3]; ! 68: memset(bmpbuf, 0x70, view_width * view_height * 3); ! 69: } ! 70: ! 71: // スクロールイベント ! 72: void ! 73: WXLunaBitmapPanel::OnScrollWin(wxScrollWinEvent& event) ! 74: { ! 75: int orient = event.GetOrientation(); ! 76: int pos = event.GetPosition(); ! 77: ! 78: if (orient == wxHORIZONTAL) { ! 79: view_x = pos * width_per_unit; ! 80: } else { ! 81: view_y = pos * height_per_unit; ! 82: } ! 83: } ! 84: ! 85: // XXX 実際にはこの辺かどこかで更新チェックをしないといけない。 ! 86: // 今は毎回全描画しているので画面サイズが大きくなると重くなる。 ! 87: ! 88: // 描画イベント (UI スレッドから呼ばれる) ! 89: void ! 90: WXLunaBitmapPanel::OnPaint(wxPaintEvent& event) ! 91: { ! 92: // 更新があれば、ここで裏バッファに描画 ! 93: Draw(); ! 94: // バッファから wxBitmap を作成 ! 95: wxImage image(view_width, view_height, bmpbuf, true); ! 96: wxBitmap bitmap(image); ! 97: ! 98: // 実画面 DC にコピー ! 99: wxPaintDC dstDC(this); ! 100: dstDC.DrawBitmap(bitmap, 0, 0); ! 101: } ! 102: ! 103: // ビットマッププレーンの内容をパネルのバックグラウンドバッファに描画する ! 104: void ! 105: WXLunaBitmapPanel::Draw() ! 106: { ! 107: int width = std::min(2048, view_width); ! 108: int height = std::min(1024, view_height); ! 109: // X 方向は32bit(ロングワード)単位で処理 ! 110: int x_offset = view_x / width_per_unit; ! 111: ! 112: for (int y = 0; y < height; y++) { ! 113: const uint32 *s = (uint32 *)&src[(view_y + y) * 256]; ! 114: uint8 *d = &bmpbuf[y * (width * 3)]; ! 115: ! 116: // dst を1ラインクリアしてから.. ! 117: memset(d, 0, width * 3); ! 118: // ON になってるドットだけ打っていく ! 119: for (int x = 0; x < width / 32; x++) { ! 120: uint32 srcdata = s[x_offset + x]; ! 121: for (int i = 0; srcdata != 0; srcdata <<= 1, i++) { ! 122: uint8 dst; ! 123: if ((int32)srcdata < 0) { ! 124: dst = 0xff; ! 125: } else { ! 126: dst = 0; ! 127: } ! 128: d[(x * 32 + i) * 3 + 0] = dst; ! 129: d[(x * 32 + i) * 3 + 1] = dst; ! 130: d[(x * 32 + i) * 3 + 2] = dst; ! 131: } ! 132: } ! 133: } ! 134: } ! 135: ! 136: // ! 137: // LUNA ビットマップウィンドウ ! 138: // ! 139: ! 140: // イベントテーブル ! 141: wxBEGIN_EVENT_TABLE(WXLunaBitmapWindow, inherited) ! 142: EVT_TIMER(wxID_ANY, WXLunaBitmapWindow::OnTimer) ! 143: wxEND_EVENT_TABLE() ! 144: ! 145: // コンストラクタ ! 146: WXLunaBitmapWindow::WXLunaBitmapWindow(wxWindow *parent, wxWindowID id, ! 147: const wxString& name) ! 148: : inherited(parent, id, name, ! 149: inherited::DEFAULT_STYLE | wxRESIZE_BORDER) ! 150: { ! 151: panel = new WXLunaBitmapPanel(this); ! 152: ! 153: // 大きさをそれに固定 ! 154: Layout(); ! 155: Fit(); ! 156: ! 157: // 更新タイマーは適当な短さにしておく ! 158: timer.SetOwner(this); ! 159: timer.Start(10); ! 160: } ! 161: ! 162: // デストラクタ ! 163: WXLunaBitmapWindow::~WXLunaBitmapWindow() ! 164: { ! 165: } ! 166: ! 167: // タイマーイベント ! 168: void ! 169: WXLunaBitmapWindow::OnTimer(wxTimerEvent& event) ! 170: { ! 171: // モニタースクリーンを更新して、更新があれば画面を再描画 ! 172: panel->Refresh(); ! 173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.