--- nono/wx/wxsubwindow.cpp 2026/04/29 17:04:39 1.1.1.3 +++ nono/wx/wxsubwindow.cpp 2026/04/29 17:05:12 1.1.1.8 @@ -4,12 +4,17 @@ // Licensed under nono-license.txt // +// +// サブウィンドウ +// + #include "wxsubwindow.h" +#include "fontmanager.h" #include "wxmainframe.h" #include "wxtextscreen.h" // -// サブウィンドウ +// サブウィンドウ (基本クラス) // // イベントテーブル @@ -17,19 +22,13 @@ wxBEGIN_EVENT_TABLE(WXSubWindow, inherit EVT_CLOSE(WXSubWindow::OnClose) wxEND_EVENT_TABLE() -// コンストラクタ (スタイル指定あり) +// コンストラクタ WXSubWindow::WXSubWindow(wxWindow *parent, wxWindowID id, const wxString& name, int style) : inherited(parent, id, name, wxDefaultPosition, wxDefaultSize, style) { } -// コンストラクタ (スタイル指定なし) -WXSubWindow::WXSubWindow(wxWindow *parent, wxWindowID id, const wxString& name) - : WXSubWindow(parent, id, name, DEFAULT_STYLE) -{ -} - // デストラクタ WXSubWindow::~WXSubWindow() { @@ -40,113 +39,74 @@ void WXSubWindow::OnClose(wxCloseEvent& event) { // ウィンドウリストから自身を削除 - gMainFrame->DeleteWindow(GetId()); + gMainFrame->DeleteWindow(this); } -// テキスト系パネルのフォントサイズを変更する +// フォントサイズ変更 void -WXSubWindow::SetFontSize(FontId fontid) +WXSubWindow::FontChanged() { - // このウィンドウの子のうち.. - wxWindowList& children = GetChildren(); - for (wxWindow *child : children) { - // すべての WXTextPanel の継承クラスだけに対して - // フォントサイズの変更を指示する。 - WXTextPanel *textpanel = dynamic_cast(child); + // WXTextPanel 派生の子コントロールに対し FontChanged() を呼ぶ + for (auto child : GetChildren()) { + auto textpanel = dynamic_cast(child); if (textpanel) { - textpanel->SetFontSize(fontid); + textpanel->FontChanged(); } } - // 大きさを変更 - Layout(); - Fit(); -} - - -// -// 縦リサイズ可能なサブウィンドウ -// - -// コンストラクタ -WXVResizeSubWindow::WXVResizeSubWindow(wxWindow *parent, wxWindowID id, - const wxString& name) - : inherited(parent, id, name, DEFAULT_STYLE | wxRESIZE_BORDER) -{ -} - -// デストラクタ -WXVResizeSubWindow::~WXVResizeSubWindow() -{ + DoSize(); } -// フォントサイズ変更 +// 中身に応じてこのウィンドウの大きさを変更 void -WXVResizeSubWindow::SetFontSize(FontId fontid) +WXSubWindow::DoSize() { - // 親クラスの処理をして.. - inherited::SetFontSize(fontid); + wxSize csize; - // フォントサイズが確定したので、継承先のウィンドウサイズ計算処理。 - // 引数なしの DoSize() は継承先ごとに実装する仮想関数、 - // そいつが共通の CalcVSize(int) を呼び出してくる。 - DoSize(); + auto *topsizer = GetSizer(); + if (topsizer) { + // Sizer があればそれがサイズを知っている + csize = topsizer->GetMinSize(); + } else { + // Sizer を使ってなければ子コントロールは1人のはず + auto& children = GetChildren(); + assert(children.GetCount() == 1); + auto child = children[0]; + csize = child->GetMinSize(); + } + SetClientSize(csize); } -// ウィンドウサイズを再計算する共通部分。 -// -// テキスト系ウィンドウではウィンドウの縦方向のリサイズは1行の高さ分ずつ -// 行いたいが、そのためにはこのウィンドウのクライアント領域が1行の高さの -// 整数倍になっている必要がある。TextScreen 自身は行の高さの整数倍だが、 -// 他に余白や別コントロールを追加して、フォントサイズも動的に変化すると -// なると、諸々自動で計算したい。 -// フォントサイズが確定したところで呼び出すこと。 -// -// fixed は TextScreen とパディングを除いたコントロールの高さ -void -WXVResizeSubWindow::CalcVSize(int fixed) +// このサブウィンドウが縦リサイズ可能なテキストパネルの場合の Layout()。 +// 本来は screen を持っている継承クラスが個別に行うことだが、定形処理なので +// ここでサブルーチンとして用意しておく。必要なら継承クラスが呼ぶこと。 +bool +WXSubWindow::LayoutTextVResize(const WXTextScreen *screen, int fixed_height) { - const wxSize& fontsize = screen->GetFontSize(); - - int pad_top = 0; - int pad_btm = 0; - - // pad は必要なパディング高 - int pad = 0; - if (fixed == 0) { - // 追加のコントロールが一切なければ1行分のパディング - pad = fontsize.y; - } else { - // 追加のコントロールがあれば、繰り上がるまでの余りをとる - pad = ((fixed + fontsize.y - 1) / fontsize.y) * fontsize.y - fixed; + if (inherited::Layout() == false) { + return false; } - if (pad > fontsize.y / 2) { - // 必要なパディングが行の 1/2 以上なら、下に 1/2、残りを上に - pad_btm = fontsize.y / 2; - pad_top = pad - pad_btm; + wxSize tsize = GetSizer()->ComputeFittingClientSize(this); + + // 高さ計算。 + // 高さの最小は fixed と TextScreen 2行分にしておく。 + int h = fixed_height; + h += screen->GetPaddingTop(); + h += screen->GetFontHeight() * 2; + h += screen->GetPaddingBottom(); + + // サイズを変える時は、大きくする時は Max を先に、小さくする時は Min を + // 先に変えないと、サイズ制約の不整合の GTK ワーニングが出てしまう。 + // うーんこの API…。 + wxSize csize = GetClientSize(); + if (tsize.x > csize.x) { + SetMaxClientSize(wxSize(tsize.x, wxDefaultCoord)); + SetMinClientSize(wxSize(tsize.x, h)); } else { - // 必要なパディングが行の 1/2 以下なら、半分ずつ - pad_btm = pad / 2; - pad_top = pad - pad_btm; + SetMinClientSize(wxSize(tsize.x, h)); + SetMaxClientSize(wxSize(tsize.x, wxDefaultCoord)); } - // パディングを設定 - wxSize size1(1, pad_top); - wxSize size2(1, pad_btm); - padding1->SetSize(size1); - padding1->SetMinSize(size1); - padding2->SetSize(size2); - padding2->SetMinSize(size2); - - // 横は固定、縦方向は1行ずつ伸縮可能 - // 最小サイズは fixed と1行分とパディング。 - wxSize tsize = topsizer->ComputeFittingWindowSize(this); - wxSize minsize = wxSize(tsize.x, fixed + fontsize.y + pad); - wxSize maxsize = wxSize(tsize.x, -1); - wxSize incsize = wxSize(0, fontsize.y); - SetSizeHints(minsize, maxsize, incsize); - - Layout(); - Fit(); + return true; }