--- nono/wx/wxstatuspanel.cpp 2026/04/29 17:05:00 1.1.1.3 +++ nono/wx/wxstatuspanel.cpp 2026/04/29 17:05:08 1.1.1.4 @@ -4,8 +4,10 @@ // Licensed under nono-license.txt // +// // ステータスパネル // + // 描画領域に対してフォントの開始位置は外枠から +4、内枠からなら +2。 // 横も同様。 // @@ -16,14 +18,17 @@ // +4 | ここからフォント #include "wxstatuspanel.h" +#include "fontmanager.h" #include "wxcolor.h" #include "wxmainframe.h" #include "wxmainview.h" #include "wxuimessage.h" #include "wxversion.h" -#include "netdriver.h" -#include "scheduler.h" +#include "ethernet.h" +#include "hostnet.h" +#include "power.h" #include "spc.h" +#include "sync.h" WXStatusPanel *gStatusPanel; @@ -32,7 +37,6 @@ wxBEGIN_EVENT_TABLE(WXStatusPanel, inher EVT_SHOW(WXStatusPanel::OnShow) EVT_SIZE(WXStatusPanel::OnSize) EVT_TIMER(wxID_ANY, WXStatusPanel::OnTimer) - EVT_PAINT(WXStatusPanel::OnPaint) EVT_LEFT_DCLICK(WXStatusPanel::OnLeftDClick) EVT_CONTEXT_MENU(WXStatusPanel::OnContextMenu) wxEND_EVENT_TABLE() @@ -46,14 +50,14 @@ static const long STATUS_PANEL_STYLE = 0 // コンストラクタ WXStatusPanel::WXStatusPanel(wxWindow *parent) - : inherited(parent, STATUS_PANEL_STYLE) + : inherited(parent, wxDefaultSize, STATUS_PANEL_STYLE) { timer.SetOwner(this); // インジケータ用のパラメータを用意。 InitIndicators(); - DoSize(); + FontChanged(); // キー入力イベントをメインビューに転送。 // このパネルへのキー入力は不要なのと、メインウィンドウ内のコントロール @@ -74,6 +78,13 @@ WXStatusPanel::WXStatusPanel(wxWindow *p // デストラクタ WXStatusPanel::~WXStatusPanel() { + while (indicators.empty() == false) { + Indicator *ind = indicators.back(); + indicators.pop_back(); + delete ind; + } + WXUIMessage::Disconnect(UIMessage::SCSI_MEDIA_CHANGE, + wxCommandEventHandler(WXStatusPanel::OnSCSIMediaChanged)); } // クローズイベント @@ -84,22 +95,6 @@ WXStatusPanel::OnClose(wxCloseEvent& eve timer.Stop(); } -// フォントサイズ変更 (外部インタフェース) -void -WXStatusPanel::SetFontSize(FontId new_fontid) -{ - // 同じなら何もしない - if (fontid == new_fontid) { - return; - } - - // フォントを変更 - UpdateFont(new_fontid); - - // サイズ変更処理 - DoSize(); -} - // 表示/非表示変更イベント // new した時は (デフォルトで表示状態なのでか状態に変更がないという扱いの // ようで) イベントは飛んでこない。同様に new 直後に Show() を明示発行しても @@ -123,19 +118,19 @@ WXStatusPanel::OnShow(wxShowEvent& event } } -// サイズ変更処理 -// サイズを変更したい時に呼ぶ (サイズが変更されたからではない)。 -// ここではサイズは fontsize にのみ依存しているので、フォントサイズが -// 変化/確定した時に呼び出すこと。 +// フォントサイズ変更 void -WXStatusPanel::DoSize() +WXStatusPanel::FontChanged() { - assert(fontid != FontId::None); + inherited::FontChanged(); + + // インジケータを再レイアウト + LayoutIndicators(); // コントロールの大きさを変更 - wxSize size(wxDefaultCoord, font_height + 8); + wxSize size = GetClientSize(); + size.y = font_height + 8; SetClientSize(size); - SetMinClientSize(size); } // サイズ変更イベント @@ -149,8 +144,8 @@ WXStatusPanel::OnSize(wxSizeEvent& event return; } - // ビットマップ作成 - bitmap.Create(size.x, size.y); + // 親クラス + inherited::OnSize(event); LayoutIndicators(); @@ -220,11 +215,13 @@ WXStatusPanel::InitIndicators() scsibus = gSPC->GetSCSIBus(); // ネットワーク - if ((bool)gNetDriver) { - if (gNetDriver->IsOpen()) { - net_ok = ENABLE; - } else { + if (gEthernet) { + hostnet = gEthernet->GetHostNet(); + assert(hostnet); + if (hostnet->GetDriverName() == "none") { net_ok = DISABLE; + } else { + net_ok = ENABLE; } // \x1e は上向き矢印、\x1f は下向き矢印 Indicator *net = new Indicator("LAN\x1e\x1f", &WXStatusPanel::DrawNet); @@ -264,25 +261,31 @@ WXStatusPanel::LayoutIndicators() int w; int h; + // 上の枠はキャンバス上端から2px + y = 2; + // そこから上下の外枠と枠と文字の間 + h = font_height + 2 + 2; + // まずは前から順に列挙して必要な幅を積算していく x = 0; for (auto ind : indicators) { - // 前の枠とは1つ開ける - if (x != 0) { - x += 1; - } + // 前の枠とは1つ空ける + x += 1; - // 上の枠はキャンバス上端から2px - y = 2; // 4 は、左右の外枠(1*2) と 枠と文字の間(1*2) w = ind->text.length() * font_width + 2 + 2; - // そこから上下の外枠と枠と文字の間 - h = font_height + 2 + 2; - ind->rect = wxRect(x, y, w, h); + ind->rect = Rect(x, y, w, h); x += w; } + // 右端も1つ空ける + x += 1; + + // この x が最小サイズなのでこれをコントロールに設定。 + // (コントロールのサイズは WXMainFrame::Layout() が設定する) + SetMinClientSize(wxSize(x, font_height + 8)); + // 全員を一旦右寄せ wxSize sz = GetClientSize(); int offsetx = sz.x - x; @@ -293,9 +296,9 @@ WXStatusPanel::LayoutIndicators() // そのうちパフォーマンスカウンタだけ中央寄せまで戻す if (indicators.size() > 0) { auto p = indicators.front(); - x = (sz.x / 2) - (p->rect.GetWidth() / 2); - if (p->rect.GetX() > x) { - p->rect.SetX(x); + x = (sz.x / 2) - (p->rect.w / 2); + if (p->rect.x > x) { + p->rect.x = x; } } @@ -304,8 +307,7 @@ WXStatusPanel::LayoutIndicators() auto si = dynamic_cast(ind); if (si && si->panel) { const auto& rect = ind->rect; - si->panel->SetPosition(wxPoint(rect.GetX(), rect.GetY())); - si->panel->SetClientSize(wxSize(rect.GetWidth(), rect.GetWidth())); + si->panel->SetSize(rect.x, rect.y, rect.w, rect.h); } } } @@ -327,11 +329,11 @@ WXStatusPanel::UpdateStat() }; // 電源オンか - MODIFY(ispower, gScheduler->IsPower()); + MODIFY(ispower, gPower->IsPower()); // パフォーマンスカウンタ - MODIFY(perf_mode, gScheduler->GetRunMode()); - MODIFY(perf_rate, gScheduler->GetPerfCounter()); + MODIFY(perf_mode, gSync->GetRunMode()); + MODIFY(perf_rate, gSync->GetPerfCounter()); // FD @@ -347,8 +349,8 @@ WXStatusPanel::UpdateStat() // およびその変化を監視しているアクティブ状態が変化したとき // に変更があったとしたいので二重になっている if (net_ok != NOT_AVAILABLE) { - MODIFY(net_tx_active, MODIFY(net_tx_pkts, gEthernet->GetTXPkts())); - MODIFY(net_rx_active, MODIFY(net_rx_pkts, gEthernet->GetRXPkts())); + MODIFY(net_tx_active, MODIFY(net_tx_pkts, hostnet->GetTXPkts())); + MODIFY(net_rx_active, MODIFY(net_rx_pkts, hostnet->GetRXPkts())); } // 電源 @@ -356,59 +358,39 @@ WXStatusPanel::UpdateStat() return updated; } -// 描画イベント -void -WXStatusPanel::OnPaint(wxPaintEvent& event) -{ - // メモリ DC に描画 - wxMemoryDC memDC; - memDC.SelectObject(bitmap); - Draw(memDC); - - // 実画面 DC にコピー - wxPaintDC dstDC(this); - wxSize size = bitmap.GetSize(); - dstDC.Blit(0, 0, size.x, size.y, &memDC, 0, 0); -} - // 描画本体 void -WXStatusPanel::Draw(wxDC& dc) +WXStatusPanel::Draw() { std::string text; - // 背景はいつものグレー。 - wxSize size = GetSize(); - dc.SetPen(wxPen(BGPANEL)); - dc.SetBrush(wxBrush(BGPANEL)); - dc.DrawRectangle(wxPoint(0, 0), size); - // なんとなく見栄えのため上下に薄い線を引く。 // 四方を線で囲むとオーバーレイウィンドウのように見えるので上下だけ。 - dc.SetPen(wxPen(UD_GREY)); - dc.DrawLine(0, 0, size.x - 1, 0); - dc.DrawLine(0, size.y - 1, size.x - 1, size.y - 1); + wxSize size = GetSize(); + bitmap.DrawLineH(UD_GREY, 0, 0, size.x); + bitmap.DrawLineH(UD_GREY, 0, size.y - 1, size.x); // 各インジケータを描画 for (auto ind : indicators) { - (this->*(ind->draw))(dc, ind); + (this->*(ind->draw))(ind); } } // パフォーマンスカウンタ void -WXStatusPanel::DrawPerf(wxDC& dc, const Indicator *ind) +WXStatusPanel::DrawPerf(const Indicator *ind) { - const wxRect& rect = ind->rect; + const Rect& rect = ind->rect; char text[16]; + const char *ffmark; // 枠 - dc.SetPen(wxPen(UD_GREY)); - dc.SetBrush(wxBrush(BGPANEL)); - dc.DrawRectangle(rect); + bitmap.DrawRect(UD_GREY, rect); // 電源オフならここまで if (ispower == false) { + bitmap.FillRect(BGPANEL, + rect.x + 1, rect.y + 1, rect.w - 2, rect.h - 2); return; } @@ -420,16 +402,14 @@ WXStatusPanel::DrawPerf(wxDC& dc, const // パフォーマンス表示は // o 高速モード指示中なら倍率表記 (115% なら 1.2x) // o 通常モード指示中ならパーセント表記 - if ((perf_mode & Scheduler::SCHED_SYNC) == 0) { + if ((perf_mode & Sync::SCHED_SYNC) == 0) { // 高速モード指示 - SetTextForeColor(UD_RED); - DrawStringSJIS(dc, rect.x + 2, rect.y + 2, "\x01"); - DrawStringSJIS(dc, rect.x + 2 + font_width, rect.y + 2, "\x01"); if (perf_mode == 0) { // 高速走行中 - DrawStringSJIS(dc, rect.x + 2 + font_width * 2, rect.y + 2, "\x01"); + ffmark = "\x01\x01\x01"; + } else { + ffmark = "\x01\x01 "; } - SetTextForeColor(*wxBLACK); // 倍率表記は1桁少ないので、表示用に最下位桁を四捨五入 int rate = perf_rate + 5; @@ -437,19 +417,21 @@ WXStatusPanel::DrawPerf(wxDC& dc, const (rate / 100), (rate % 100) / 10); } else { // 通常モード指示 - + ffmark = " "; snprintf(text, sizeof(text), "%4d%%", perf_rate); } - DrawStringSJIS(dc, rect.x + 2 + font_width * 3, rect.y + 2, text); + + DrawStringSJIS(UD_RED, rect.x + 2, rect.y + 2, ffmark); + DrawStringSJIS(rect.x + 2 + font_width * 3, rect.y + 2, text); } // SCSI デバイス側のアクセスランプ // 本体ではなく各 SCSI デバイス側 (外付け HDD の前面とか) にあるやつ。 void -WXStatusPanel::DrawSCSI(wxDC& dc, const Indicator *ind) +WXStatusPanel::DrawSCSI(const Indicator *ind) { - wxColour fg; - wxColour bg; + Color fg; + Color bg; uint idmask; const auto si = dynamic_cast(ind); @@ -457,7 +439,7 @@ WXStatusPanel::DrawSCSI(wxDC& dc, const idmask = 1U << si->GetId(); if ((scsi_loaded & idmask) != 0) { - fg = *wxBLACK; + fg = UD_BLACK; } else { fg = UD_GREY; } @@ -472,19 +454,19 @@ WXStatusPanel::DrawSCSI(wxDC& dc, const bg = BGPANEL; } - DrawTextLED(dc, ind, fg, bg); + DrawTextLED(ind, fg, bg); } // ネットワーク(LAN) void -WXStatusPanel::DrawNet(wxDC& dc, const Indicator *ind) +WXStatusPanel::DrawNet(const Indicator *ind) { - wxColour fg; - wxColour bg = BGPANEL; - const wxRect& rect = ind->rect; + Color fg; + Color bg = BGPANEL; + const Rect& rect = ind->rect; if (net_ok) { - fg = *wxBLACK; + fg = UD_BLACK; if (net_tx_active || net_rx_active) { bg = UD_YELLOW_GREEN; } @@ -493,9 +475,8 @@ WXStatusPanel::DrawNet(wxDC& dc, const I } // 枠 - dc.SetPen(wxPen(UD_GREY)); - dc.SetBrush(wxBrush(bg)); - dc.DrawRectangle(rect); + bitmap.FillRect(bg, rect); + bitmap.DrawRect(UD_GREY, rect); int x = rect.x + 2; int y = rect.y + 2; @@ -505,21 +486,21 @@ WXStatusPanel::DrawNet(wxDC& dc, const I switch (c) { case '\x1e': // 上向き矢印 if (net_tx_active) { - fg = *wxBLACK; + fg = UD_BLACK; } else { fg = UD_GREY; } break; case '\x1f': // 下向き矢印 if (net_rx_active) { - fg = *wxBLACK; + fg = UD_BLACK; } else { fg = UD_GREY; } break; } SetTextColor(fg, bg); - DrawChar1(dc, x, y, c); + DrawChar1(x, y, c); x += font_width; } ResetTextColor(); @@ -527,26 +508,24 @@ WXStatusPanel::DrawNet(wxDC& dc, const I // 電源LED? void -WXStatusPanel::DrawPower(wxDC& dc, const Indicator *ind) +WXStatusPanel::DrawPower(const Indicator *ind) { - DrawTextLED(dc, ind, *wxBLACK, UD_YELLOW_GREEN); + DrawTextLED(ind, UD_BLACK, UD_YELLOW_GREEN); } // 共通の描画処理。 // ind->text を前景色 fg、背景色 bg で描画するだけの場合。 void -WXStatusPanel::DrawTextLED(wxDC& dc, const Indicator *ind, - const wxColour& fg, const wxColour& bg) +WXStatusPanel::DrawTextLED(const Indicator *ind, Color fg, Color bg) { - const wxRect& rect = ind->rect; + const Rect& rect = ind->rect; // 枠 - dc.SetPen(wxPen(UD_GREY)); - dc.SetBrush(wxBrush(bg)); - dc.DrawRectangle(rect); + bitmap.FillRect(bg, rect); + bitmap.DrawRect(UD_GREY, rect); SetTextColor(fg, bg); - DrawStringSJIS(dc, rect.x + 2, rect.y + 2, ind->text.c_str()); + DrawStringSJIS(rect.x + 2, rect.y + 2, ind->text.c_str()); ResetTextColor(); } @@ -558,7 +537,7 @@ WXStatusPanel::OnLeftDClick(wxMouseEvent for (auto ind : indicators) { // dclick を処理できる枠内なら - if (ind->rect.Contains(pt) && ind->dclick != NULL) { + if (ind->rect.Contains(pt.x, pt.y) && ind->dclick != NULL) { (this->*(ind->dclick))(ind); break; } @@ -570,7 +549,7 @@ void WXStatusPanel::DClickPerf(const Indicator *ind) { // モードを切り替える - gScheduler->SetFullSpeed(!gScheduler->GetFullSpeed()); + gSync->RequestFullSpeed(!gSync->GetFullSpeed()); } // コンテキストメニューイベント @@ -582,7 +561,7 @@ WXStatusPanel::OnContextMenu(wxContextMe for (auto ind : indicators) { // コンテキストメニューを処理できる枠内なら const auto si = dynamic_cast(ind); - if (si && si->contextmenu && ind->rect.Contains(pos)) { + if (si && si->contextmenu && ind->rect.Contains(pos.x, pos.y)) { (this->*(si->contextmenu))(ind); break; }