--- nono/wx/wxscrollbar.cpp 2026/04/29 17:05:19 1.1.1.3 +++ nono/wx/wxscrollbar.cpp 2026/04/29 17:05:44 1.1.1.4 @@ -84,8 +84,10 @@ wxEND_EVENT_TABLE() // 本家の wxScrollBar は style のデフォルトが wxSB_HORIZONTAL だが、 // うちではデフォルト引数にはしない。 WXScrollBar::WXScrollBar(wxWindow *parent, wxWindowID id, long style) - : inherited(parent, id, wxDefaultPosition, wxSize(16, 16), 0) + : inherited(parent, id) { + SetName("WXScrollBar"); + if (style == wxSB_VERTICAL) { is_vertical = true; } @@ -105,34 +107,51 @@ void WXScrollBar::FontChanged() { inherited::FontChanged(); + DPRINTF("%s %d\n", __method__, font_height); - int newpx; switch (font_height) { case 12: - newpx = 16; + subpx = 16; break; case 16: - newpx = 20; + subpx = 20; break; case 24: - newpx = 32; + subpx = 32; break; default: PANIC("Unexpected font_height=%d", font_height); } // つまみの最小サイズ。適当に幅の半分。 - thumbmin = newpx / 2; + thumbmin = subpx / 2; + + Fit(); +} + +void +WXScrollBar::Fit() +{ + // 最小サイズを設定。 + wxSize minsize; + if (is_vertical) { + minsize.x = subpx; + minsize.y = font_height; + } else { + minsize.x = font_width * 2; + minsize.y = subpx; + } + DPRINTF("%s GetSize=(%d,%d) Best=(%d,%d)\n", __method__, + GetSize().x, GetSize().y, minsize.x, minsize.y); + SetSizeHints(minsize, wxDefaultSize); - // コントロールの大きさを変更 - wxSize size = GetClientSize(); + // 主方向は最小サイズを下回らなければ維持、 + // 副方向は常に規定サイズ。 if (is_vertical) { - size.x = newpx; + SetSize(subpx, GetSize().y); } else { - size.y = newpx; + SetSize(GetSize().x, subpx); } - SetClientSize(size); - SetMinClientSize(size); } // スクロールバーのパラメータを設定する。 @@ -159,7 +178,7 @@ WXScrollBar::SetScrollParam(int pos_, in bool WXScrollBar::SetThumbPosition(int pos) { - // パラメータセット前に OnSize されるとここに来る + // パラメータセット前にリサイズされるとここに来る if (range < 1) { return false; } @@ -241,31 +260,22 @@ WXScrollBar::MoveThumb(int pos) } } -// コントロールの主方向(スクロール方向)の最小ピクセル数を返す -int -WXScrollBar::GetMinLength() const -{ - return thumbmin + BORDER_LT + BORDER_RB; -} - -// サイズイベント void WXScrollBar::OnSize(wxSizeEvent& event) { - auto s __unused = event.GetSize(); - DPRINTF("OnSize %d,%d\n", s.x, s.y); - - // 親クラス - inherited::OnSize(event); + const wxSize& size = GetSize(); + DPRINTF("%s size=(%d,%d)\n", __method__, size.x, size.y); + // スクロールバーの論理パラメータは変わらず、描画情報が変わる。 if (is_vertical) { - range_px = bitmap.GetHeight() - BORDER_LT - BORDER_RB; + range_px = size.y - BORDER_LT - BORDER_RB; } else { - range_px = bitmap.GetWidth() - BORDER_LT - BORDER_RB; + range_px = size.x - BORDER_LT - BORDER_RB; } - // range_px が変わったので再描画 SetThumbPosition(thumbpos); + + event.Skip(); } // マウスイベント @@ -365,8 +375,16 @@ WXScrollBar::PosCmp() const void WXScrollBar::Draw() { - const int& w = bitmap.GetWidth(); - const int& h = bitmap.GetHeight(); + // パラメータセット前に表示してしまうとここに来る。 + if (__predict_false(range < 1)) { + return; + } + + const int w = bitmap.GetWidth(); + const int h = bitmap.GetHeight(); + if (__predict_false(w < 4 || h < 4)) { + return; + } if (is_vertical) { // 背景 @@ -376,7 +394,7 @@ WXScrollBar::Draw() bitmap.FillRect(UD_GREY, 0, 1, w - 1, h - 2); // つまみ - bitmap.FillRect(BGPANEL, 1, p1, w - 4, p2 - p1 - 1); + bitmap.FillRect(BGPANEL, 1, p1, w - 3, p2 - p1 - 1); bitmap.DrawLineH(UD_BLACK, 1, p2 - 1, w - 1); bitmap.DrawLineV(UD_BLACK, w - 2, p1, p2); } else { @@ -387,7 +405,7 @@ WXScrollBar::Draw() bitmap.FillRect(UD_GREY, 1, 0, w - 2, h - 1); // つまみ - bitmap.FillRect(BGPANEL, p1, 1, p2 - p1 - 1, h - 4); + bitmap.FillRect(BGPANEL, p1, 1, p2 - p1 - 1, h - 3); bitmap.DrawLineV(UD_BLACK, p2 - 1, 1, h - 1); bitmap.DrawLineH(UD_BLACK, p1, h - 2, p2); }