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