--- nono/wx/wxlcdwindow.cpp 2026/04/29 17:04:39 1.1.1.1 +++ nono/wx/wxlcdwindow.cpp 2026/04/29 17:04:53 1.1.1.2 @@ -9,6 +9,7 @@ // #include "wxlcdwindow.h" +#include "wxbmp.h" #include "wxcolor.h" #include "wxtextscreen.h" #include "lcd.h" @@ -34,10 +35,7 @@ WXLCDPanel::WXLCDPanel(wxWindow *parent) : inherited(parent, wxID_ANY, wxDefaultPosition, wxSize(PANEL_WIDTH, PANEL_HEIGHT)) { - bmpbuf.reset(new uint8 [PANEL_WIDTH * PANEL_HEIGHT * 3]); - memset(&bmpbuf[0], 0x70, PANEL_WIDTH * PANEL_HEIGHT * 3); - image.reset(new wxImage(PANEL_WIDTH, PANEL_HEIGHT, bmpbuf.get(), true)); - bitmap.reset(new wxBitmap(*image)); + bitmap.Create(PANEL_WIDTH, PANEL_HEIGHT); count = (uint32)-1; ddram = gLCD->GetDDRAM(); @@ -50,9 +48,6 @@ WXLCDPanel::WXLCDPanel(wxWindow *parent) // デストラクタ WXLCDPanel::~WXLCDPanel() { - bitmap.reset(); - image.reset(); - bmpbuf.reset(); } // タイマーイベント @@ -77,7 +72,7 @@ WXLCDPanel::OnPaint(wxPaintEvent& event) { // メモリ DC に描画 wxMemoryDC memDC; - memDC.SelectObject(*bitmap); + memDC.SelectObject(bitmap); Draw(memDC); // 実画面 DC にコピー @@ -92,7 +87,7 @@ WXLCDPanel::Draw(wxDC& dc) // 背景 dc.SetPen(UD_CREAM); dc.SetBrush(UD_CREAM); - dc.DrawRectangle(wxPoint(0, 0), wxSize(PANEL_WIDTH, PANEL_HEIGHT)); + dc.DrawRectangle(wxPoint(0, 0), bitmap.GetSize()); for (int y = 0; y < 2; y++) { for (int x = 0; x < 16; x++) { @@ -143,7 +138,6 @@ WXLCDWindow::WXLCDWindow(wxWindow *paren panel = new WXLCDPanel(this); // 大きさをそれに固定 - Layout(); Fit(); } @@ -156,8 +150,8 @@ WXLCDWindow::~WXLCDWindow() // LCD キャラクタパネル // -#define CP_WIDTH (N * (1 + 6 * 16)) -#define CP_HEIGHT (N * (1 + 9 * 16)) +#define CP_WIDTH (N * (1 + 6 * (16 + 1 + 16))) +#define CP_HEIGHT (N * (1 + 9 * 8)) // イベントテーブル wxBEGIN_EVENT_TABLE(WXLCDCharPanel, inherited) @@ -166,21 +160,14 @@ wxEND_EVENT_TABLE() // コンストラクタ WXLCDCharPanel::WXLCDCharPanel(wxWindow *parent) - : inherited(parent, wxID_ANY, wxDefaultPosition, - wxSize(CP_WIDTH, CP_HEIGHT)) + : inherited(parent, wxSize(CP_WIDTH, CP_HEIGHT)) { - bmpbuf.reset(new uint8 [CP_WIDTH * CP_HEIGHT * 3]); - memset(&bmpbuf[0], 0x70, CP_WIDTH * CP_HEIGHT * 3); - image.reset(new wxImage(CP_WIDTH, CP_HEIGHT, bmpbuf.get(), true)); - bitmap.reset(new wxBitmap(*image)); + bitmap.Create(CP_WIDTH, CP_HEIGHT); } // デストラクタ WXLCDCharPanel::~WXLCDCharPanel() { - bitmap.reset(); - image.reset(); - bmpbuf.reset(); } // 描画イベント (UI スレッドから呼ばれる) @@ -189,7 +176,7 @@ WXLCDCharPanel::OnPaint(wxPaintEvent& ev { // メモリ DC に描画 wxMemoryDC memDC; - memDC.SelectObject(*bitmap); + memDC.SelectObject(bitmap); Draw(memDC); // 実画面 DC にコピー @@ -204,19 +191,18 @@ WXLCDCharPanel::Draw(wxDC& dc) wxSize dotsize = wxSize(N, N); // 背景 - // XXX LIGHT_GREY を textscreen と共用すること - dc.SetPen(*wxLIGHT_GREY); - dc.SetBrush(*wxLIGHT_GREY); - dc.DrawRectangle(wxPoint(0, 0), wxSize(CP_WIDTH, CP_HEIGHT)); + dc.SetPen(BGPANEL); + dc.SetBrush(BGPANEL); + dc.DrawRectangle(wxPoint(0, 0), bitmap.GetSize()); // フォントは 5x8 (最下行はカーソル用に空けてあるので実際は 5x7)。 // 実際には 0xe0 以降には 5x10 フォントが混在しているのだが、その // モードはサポートしていないので今の所全部 5x8 としてある。 - for (int ch = 0; ch < 256; ch++) { - // この文字の左上座標 (スケール前) - int cx = 1 + (ch % 16) * 6; - int cy = 1 + (ch / 16) * 9; + // cx, cy はこの文字の左上座標 (スケール前) + int cx = 1; + int cy = 1; + for (int ch = 0; ch < 256; ch++) { const uint8 *font = gLCD->GetFont(ch); for (int py = 0; py < 8; py++) { uint8 line = *font++; @@ -237,6 +223,18 @@ WXLCDCharPanel::Draw(wxDC& dc) line <<= 1; } } + + cx += 6; + if (ch % 16 == 15) { + // 行折り返し + cx -= 6 * 16; + cy += 9; + // 0x80 以降は右側に作る + if (ch == 127) { + cx += 6 * (16 + 1/*中央の余白*/); + cy = 1; + } + } } } @@ -248,19 +246,54 @@ WXLCDCharPanel::Draw(wxDC& dc) WXLCDMonitor::WXLCDMonitor(wxWindow *parent, wxWindowID id) : inherited(parent, id, _("LCD")) { + // top + // | +--------------------------+ + // v | 上余白 | + // +------+------------+------+ + // |左余白| TextScreen |右余白| + // +------+-----------++------+ + // |左余白| CharPanel | 右余白| + // +------+-----------+-------+ + // | 下余白 | + // +--------------------------+ wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); + // 上余白 + topsizer->Add(new WXPaddingPanel(this), 0, wxEXPAND); + + // 2段目 + wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL); + topsizer->Add(hbox1, 0, wxEXPAND); + + // 2段目の左余白 + hbox1->Add(new WXPaddingPanel(this), 0, wxEXPAND); + monpanel = new WXTextScreen(this, *gLCD); - topsizer->Add(monpanel, 0, wxEXPAND | wxALL, DefaultPadding); + hbox1->Add(monpanel, 0, wxEXPAND); + + // 2段目の右余白 + hbox1->Add(new WXPaddingPanel(this), 0, wxEXPAND); + + // 3段目 + wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL); + topsizer->Add(hbox2, 0, wxEXPAND); + + // 3段目の左余白 + hbox2->Add(new WXPaddingPanel(this), 0, wxEXPAND); chrpanel = new WXLCDCharPanel(this); - topsizer->Add(chrpanel, 0, wxEXPAND | wxRIGHT | wxLEFT | wxBOTTOM, - DefaultPadding); + hbox2->Add(chrpanel, 0, wxEXPAND); + + // 3段目の右余白 + // ここの1でこの右余白が空き全部を使用するので空き地が埋まる + hbox2->Add(new WXPaddingPanel(this), 1, wxEXPAND); + + // 下余白 + topsizer->Add(new WXPaddingPanel(this), 0, wxEXPAND); SetSizer(topsizer); // 大きさをそれに固定 - Layout(); Fit(); }