--- nono/wx/wxsubwindow.cpp 2026/04/29 17:04:53 1.1.1.4 +++ nono/wx/wxsubwindow.cpp 2026/04/29 17:05:08 1.1.1.7 @@ -4,13 +4,17 @@ // Licensed under nono-license.txt // +// +// サブウィンドウ +// + #include "wxsubwindow.h" -#include "wxcolor.h" +#include "fontmanager.h" #include "wxmainframe.h" #include "wxtextscreen.h" // -// サブウィンドウ +// サブウィンドウ (基本クラス) // // イベントテーブル @@ -18,16 +22,10 @@ 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, style) -{ -} - -// コンストラクタ (スタイル指定なし) -WXSubWindow::WXSubWindow(wxWindow *parent, wxWindowID id, const wxString& name) - : WXSubWindow(parent, id, name, DEFAULT_STYLE) + : inherited(parent, id, name, wxDefaultPosition, wxDefaultSize, style) { } @@ -41,26 +39,42 @@ 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(); } } - // 大きさを変更 - Fit(); + DoSize(); +} + +// 中身に応じてこのウィンドウの大きさを変更 +void +WXSubWindow::DoSize() +{ + wxSize csize; + + 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); } @@ -80,95 +94,48 @@ WXVResizeSubWindow::~WXVResizeSubWindow( { } -// フォントサイズ変更 void -WXVResizeSubWindow::SetFontSize(FontId fontid) +WXVResizeSubWindow::FontChanged() { - // 親クラスの処理をして.. - inherited::SetFontSize(fontid); - - // フォントサイズが確定したので、継承先のウィンドウサイズ計算処理。 - // 引数なしの DoSize() は継承先ごとに実装する仮想関数、 - // そいつが共通の CalcVSize(int) を呼び出してくる。 + screen->FontChanged(); + Layout(); DoSize(); } -// ウィンドウサイズを再計算する共通部分。 -// -// テキスト系ウィンドウではウィンドウの縦方向のリサイズは1行の高さ分ずつ -// 行いたいが、そのためにはこのウィンドウのクライアント領域が1行の高さの -// 整数倍になっている必要がある。TextScreen 自身は行の高さの整数倍だが、 -// 他に余白や別コントロールを追加して、フォントサイズも動的に変化すると -// なると、諸々自動で計算したい。 -// フォントサイズが確定したところで呼び出すこと。 -// -// fixed は TextScreen とパディングを除いたコントロールの高さ void -WXVResizeSubWindow::CalcVSize(int fixed) +WXVResizeSubWindow::DoSize() { - const wxSize& fontsize = screen->GetFontSize(); - - int pad_top = 0; - int pad_btm = 0; + wxSize tsize = GetSizer()->ComputeFittingClientSize(this); + SetClientSize(tsize); +} - // pad は必要なパディング高 - int pad = 0; - if (fixed == 0) { - // 追加のコントロールが一切なければ1行分のパディング - pad = fontsize.y; - } else { - // 追加のコントロールがあれば、繰り上がるまでの余りをとる - pad = ((fixed + fontsize.y - 1) / fontsize.y) * fontsize.y - fixed; +bool +WXVResizeSubWindow::Layout() +{ + 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); - - Fit(); -} - - -// -// サブウィンドウの四辺に置くためのパディングパネル -// - -// コンストラクタ (サイズ指定なし) -WXPaddingPanel::WXPaddingPanel(wxWindow *parent) - : WXPaddingPanel(parent, wxSize(DefaultPadding, DefaultPadding)) -{ -} - -// コンストラクタ (サイズ指定あり) -WXPaddingPanel::WXPaddingPanel(wxWindow *parent, const wxSize& size) - : inherited(parent, wxID_ANY, wxDefaultPosition, size) -{ - SetBackgroundColour(BGPANEL); -} - -// デストラクタ -WXPaddingPanel::~WXPaddingPanel() -{ + return true; }