--- nono/wx/wxplanemonitor.cpp 2026/04/29 17:05:16 1.1.1.2 +++ nono/wx/wxplanemonitor.cpp 2026/04/29 17:05:19 1.1.1.3 @@ -15,6 +15,14 @@ #include "planevram.h" #include "videoctlr.h" +//#define WINDOW_DEBUG 1 + +#if defined(WINDOW_DEBUG) +#define DPRINTF(fmt...) printf(fmt) +#else +#define DPRINTF(fmt...) /**/ +#endif + enum { ID_PLANE0 = IDGROUP_PLANEVRAM, ID_PLANE1, @@ -252,18 +260,13 @@ WXPlaneVRAMPanel::WXPlaneVRAMPanel(wxWin // Sizer 使わず自前でレイアウトする。 SetAutoLayout(true); - // 最小値は適当 - int vscr_width = vscroll->GetClientSize().x; - int hscr_height = hscroll->GetClientSize().y; - SetMinClientSize(wxSize(16 + vscr_width, 16 + hscr_height)); - SetMaxClientSize(wxSize(viewctl->virtual_width + vscr_width, - viewctl->virtual_height + hscr_height)); - // スクロールバーからの通知イベントは表示パネルへ回す vscroll->Connect(NONO_EVT_SCROLL, wxScrollEventHandler(WXPlaneVRAMBitmapPanel::OnScroll), NULL, viewctl); hscroll->Connect(NONO_EVT_SCROLL, wxScrollEventHandler(WXPlaneVRAMBitmapPanel::OnScroll), NULL, viewctl); + + DPRINTF("Panel.ctor end\n"); } // デストラクタ @@ -274,27 +277,80 @@ WXPlaneVRAMPanel::~WXPlaneVRAMPanel() bool WXPlaneVRAMPanel::Layout() { + DPRINTF("Panel.Layout\n"); if (inherited::Layout() == false) { return false; } - // コントロールを配置 const wxSize size = GetClientSize(); - int vscr_width = vscroll->GetClientSize().x; - int hscr_height = hscroll->GetClientSize().y; - int view_width = size.x - vscr_width; - int view_height = size.y - hscr_height; + DPRINTF("Panel.Layout inherited, client=(%d,%d)\n", size.x, size.y); + wxSize vscr = vscroll->GetClientSize(); + wxSize hscr = hscroll->GetClientSize(); + DPRINTF("Panel.Layout vscr=(%d,%d) hscr=(%d,%d)\n", + vscr.x, vscr.y, hscr.x, hscr.y); + // 主方向(スクロール方向) の最小サイズ + int vmin = vscroll->GetMinLength(); + int hmin = hscroll->GetMinLength(); + + // 最小サイズはスクロールバーの大きさで制約がかかる。 + // (VRAM パネルなので実際はもっと広くてもいいかも知れない) + SetMinClientSize(wxSize(hmin + vscr.x, vmin + hscr.y)); + SetMaxClientSize(wxSize(viewctl->virtual_width + vscr.x, + viewctl->virtual_height + hscr.y)); + +#if defined(WINDOW_DEBUG) + const wxSize& min = GetMinClientSize(); + const wxSize& max = GetMaxClientSize(); + const wxSize& cli = GetClientSize(); + printf("Panel.Layout min=(%d,%d) max=(%d,%d) client=(%d,%d)\n", + min.x, min.y, max.x, max.y, cli.x, cli.y); +#endif + + // コントロールを配置 + int view_width = size.x - vscr.x; + int view_height = size.y - hscr.y; + DPRINTF("Panel.Layout view=(%d,%d)\n", view_width, view_height); + // 最低でも 1px ないと GTK とかに怒られる + if (view_width < 1) { + view_width = 1; + } + if (view_height < 1) { + view_height = 1; + } + viewctl->SetSize(0, 0, view_width, view_height); - vscroll->SetSize(view_width, 0, vscr_width, view_height); - hscroll->SetSize(0, view_height, view_width, hscr_height); - corner->SetSize(view_width, view_height, vscr_width, hscr_height); + vscroll->SetSize(view_width, 0, vscr.x, view_height); + hscroll->SetSize(0, view_height, view_width, hscr.y); + corner->SetSize(view_width, view_height, vscr.x, hscr.y); // XXX 内部のコントロールのサイズが確定してからでないと DoSize() できない DoSize(size); + DPRINTF("Panel.Layout done\n"); return true; } +// フォントサイズ変更 +void +WXPlaneVRAMPanel::FontChanged() +{ + // このパネル自体はフォントを出力しないが + // フォントサイズ変更に反応する必要があるため、用意している。 + + // 自身がフォントを使わないので呼ばなくてもいいが、お作法として。 + inherited::FontChanged(); + DPRINTF("Panel.FontChanged %d\n", font_height); + + // SubWindow はパネルの FontChanged() までは呼んでくれるけど、 + // パネルが子を持ってるケースは自力で伝搬させるとかする必要がある。 + hscroll->FontChanged(); + vscroll->FontChanged(); + + // レイアウト変更も手動で指示。 + Layout(); + DPRINTF("Panel.FontChanged end\n"); +} + // サイズ変更イベント void WXPlaneVRAMPanel::OnSize(wxSizeEvent& event) @@ -302,6 +358,7 @@ WXPlaneVRAMPanel::OnSize(wxSizeEvent& ev // Mac ではウィンドウ作成時に 0 以下の値が来ることがある。 // GTK では 1 で来ることがある。 wxSize size = event.GetSize(); + DPRINTF("Panel.OnSize (%d,%d)\n", size.x, size.y); if (size.x <= 1 || size.y <= 1) { return; } @@ -319,6 +376,7 @@ void WXPlaneVRAMPanel::DoSize(wxSize size) { wxSize viewsize = viewctl->GetClientSize(); + DPRINTF("Panel.DoSize: view=(%d,%d)\n", viewsize.x, viewsize.y); int virtual_width = viewctl->virtual_width; int virtual_height = viewctl->virtual_height; Rect& view = viewctl->view; @@ -479,7 +537,9 @@ WXPlaneVRAMWindow::WXPlaneVRAMWindow(wxW ctrlpanel->SetSizer(ctrlbox); ctrlbox->SetSizeHints(ctrlpanel); - statuspanel = new WXTextScreen(this, nnSize(50, nplane)); + // 情報パネルは大きさを固定 + statuspanel = new WXTextScreen(this, nnSize(60, nplane)); + statuspanel->SetMinClientSize(statuspanel->GetDesiredSize()); topsizer->Add(statuspanel, 0, wxEXPAND); viewpanel = new WXPlaneVRAMPanel(this); @@ -487,11 +547,7 @@ WXPlaneVRAMWindow::WXPlaneVRAMWindow(wxW SetSizer(topsizer); - // 最小サイズは上コントロール部の横幅が最小基準 - wxSize minsize = ctrlpanel->GetMinClientSize(); - minsize.y += viewpanel->GetMinClientSize().y; - SetMinClientSize(minsize); - // 最大サイズは DoScale() 内で設定している + FontChanged(); // 1bpp ならプレーン選択はすべて無効、それ以外はすべて有効。 if (nplane == 1) { @@ -536,6 +592,8 @@ WXPlaneVRAMWindow::WXPlaneVRAMWindow(wxW // 更新タイマーはモニターパネル同様の 30Hz にしておく。 timer.SetOwner(this); timer.Start(33); + + DPRINTF("Window.ctor end\n"); } // デストラクタ @@ -546,10 +604,30 @@ WXPlaneVRAMWindow::~WXPlaneVRAMWindow() void WXPlaneVRAMWindow::FontChanged() { - // 親 (wxSubWindow) の FontChanged() を実行しないようにするための - // 空のオーバーライド。親の FontChanged() が呼ぶ DoSize() が - // ウィンドウサイズを変更しようとするが、ここはテキストフォントを - // 持っていないのでその操作は不要。うーん。 + DPRINTF("Window.FontChanged\n"); + inherited::FontChanged(); + DPRINTF("Window.FontChanged inherited\n"); + + // 子コントロールのサイズが変わったのでウィンドウサイズを再計算。 + // 最小サイズは上コントロール部と情報パネルの横幅のうち大きい方が基準。 + wxSize minsize = ctrlpanel->GetMinClientSize(); + const wxSize& statsize = statuspanel->GetDesiredSize(); + const wxSize& statmin __unused = statuspanel->GetMinClientSize(); + const wxSize& viewmin __unused = viewpanel->GetMinClientSize(); + DPRINTF("Window.FontChanged ctrl.min=(%d,%d)\n", minsize.x, minsize.y); + DPRINTF("Window.FontChanged stat.min=(%d,%d) des=(%d,%d)\n", + statmin.x, statmin.y, statsize.x, statsize.y); + DPRINTF("Window.FontChanged view.min=(%d,%d)\n", viewmin.x, viewmin.y); + + minsize.x = std::max(minsize.x, statsize.x); + minsize.y += statsize.y; + minsize.y += viewmin.y; + DPRINTF("Window.FontChanged SetMin=(%d,%d)\n", minsize.x, minsize.y); + SetMinClientSize(minsize); + SetClientSize(minsize); + Layout(); + + DPRINTF("Window.FontChanged end\n"); } // プレーン選択のチェックボックスイベント