diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-09-08 09:30:35 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-09-21 20:10:06 +0200 |
commit | af90b8089405d6f042207f5639e750f08798ae92 (patch) | |
tree | 0af8401f534cbce9a11e64c1819ef84413ddd912 /sfx2/source/dialog/infobar.cxx | |
parent | 416c11d189a18a08c28135b8aa5e0f12cd51dcd6 (diff) |
weld infobars
note: "pushed" status listener case dropped. Doesn't seem to be an expectation
for it to something in infobars, and there doesn't seem to be a working case
anyway.
Change-Id: I7869cc05de9918f0dd70e28b0087205db6c9506c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101945
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sfx2/source/dialog/infobar.cxx')
-rw-r--r-- | sfx2/source/dialog/infobar.cxx | 380 |
1 files changed, 198 insertions, 182 deletions
diff --git a/sfx2/source/dialog/infobar.cxx b/sfx2/source/dialog/infobar.cxx index fd64691ffa99..580bd6685801 100644 --- a/sfx2/source/dialog/infobar.cxx +++ b/sfx2/source/dialog/infobar.cxx @@ -8,6 +8,7 @@ */ #include <basegfx/polygon/b2dpolygon.hxx> +#include <comphelper/dispatchcommand.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx> #include <drawinglayer/primitive2d/PolyPolygonStrokePrimitive2D.hxx> @@ -21,11 +22,13 @@ #include <sfx2/objface.hxx> #include <sfx2/sfxsids.hrc> #include <sfx2/viewfrm.hxx> -#include <vcl/button.hxx> -#include <vcl/fixed.hxx> #include <vcl/decoview.hxx> +#include <vcl/image.hxx> #include <vcl/settings.hxx> #include <vcl/svapp.hxx> +#include <vcl/virdev.hxx> +#include <vcl/weldutils.hxx> +#include <bitmaps.hlst> using namespace std; using namespace drawinglayer::geometry; @@ -37,8 +40,6 @@ using namespace css::frame; namespace { -const long INFO_BAR_BASE_HEIGHT = 40; - void GetInfoBarColors(InfobarType ibType, BColor& rBackgroundColor, BColor& rForegroundColor, BColor& rMessageColor) { @@ -79,54 +80,39 @@ OUString GetInfoBarIconName(InfobarType ibType) switch (ibType) { case InfobarType::INFO: - aRet = "vcl/res/infobox.svg"; + aRet = "vcl/res/infobox.png"; break; case InfobarType::SUCCESS: - aRet = "vcl/res/successbox.svg"; + aRet = "vcl/res/successbox.png"; break; case InfobarType::WARNING: - aRet = "vcl/res/warningbox.svg"; + aRet = "vcl/res/warningbox.png"; break; case InfobarType::DANGER: - aRet = "vcl/res/errorbox.svg"; + aRet = "vcl/res/errorbox.png"; break; } return aRet; } -class SfxCloseButton : public PushButton -{ - basegfx::BColor m_aBackgroundColor; - basegfx::BColor m_aForegroundColor; - -public: - explicit SfxCloseButton(vcl::Window* pParent) - : PushButton(pParent, 0) - { - basegfx::BColor aMessageColor; - GetInfoBarColors(InfobarType::WARNING, m_aBackgroundColor, m_aForegroundColor, - aMessageColor); - } +} // anonymous namespace - virtual void Paint(vcl::RenderContext& rRenderContext, - const ::tools::Rectangle& rRect) override; +void SfxInfoBarWindow::SetCloseButtonImage() +{ + Size aSize = Image(StockImage::Yes, CLOSEDOC).GetSizePixel(); + aSize = Size(aSize.Width() * 1.5, aSize.Height() * 1.5); - void setBackgroundColor(const basegfx::BColor& rColor); - void setForegroundColor(const basegfx::BColor& rColor); -}; + VclPtr<VirtualDevice> xDevice(m_xCloseBtn->create_virtual_device()); + xDevice->SetOutputSizePixel(aSize); -void SfxCloseButton::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) -{ Point aBtnPos(0, 0); - if (GetButtonState() & DrawButtonFlags::Pressed) - aBtnPos.Move(Size(1, 1)); const ViewInformation2D aNewViewInfos; const unique_ptr<BaseProcessor2D> pProcessor( - createBaseProcessor2DFromOutputDevice(rRenderContext, aNewViewInfos)); + createBaseProcessor2DFromOutputDevice(*xDevice, aNewViewInfos)); - const ::tools::Rectangle aRect(aBtnPos, PixelToLogic(GetSizePixel())); + const ::tools::Rectangle aRect(aBtnPos, xDevice->PixelToLogic(aSize)); drawinglayer::primitive2d::Primitive2DContainer aSeq(2); @@ -138,12 +124,8 @@ void SfxCloseButton::Paint(vcl::RenderContext& rRenderContext, const ::tools::Re aPolygon.append(B2DPoint(aRect.Left(), aRect.Bottom())); aPolygon.setClosed(true); - Color aBackgroundColor(m_aBackgroundColor); - if (IsMouseOver() || HasFocus()) - aBackgroundColor.ApplyTintOrShade(-2000); - PolyPolygonColorPrimitive2D* pBack - = new PolyPolygonColorPrimitive2D(B2DPolyPolygon(aPolygon), aBackgroundColor.getBColor()); + = new PolyPolygonColorPrimitive2D(B2DPolyPolygon(aPolygon), m_aBackgroundColor); aSeq[0] = pBack; LineAttribute aLineAttribute(m_aForegroundColor, 2.0); @@ -167,187 +149,186 @@ void SfxCloseButton::Paint(vcl::RenderContext& rRenderContext, const ::tools::Re aSeq[1] = pCross; pProcessor->process(aSeq); + + m_xCloseBtn->set_item_image("close", xDevice); } -void SfxCloseButton::setBackgroundColor(const basegfx::BColor& rColor) +class ExtraButton { - m_aBackgroundColor = rColor; -} +private: + std::unique_ptr<weld::Builder> m_xBuilder; + std::unique_ptr<weld::Container> m_xContainer; + std::unique_ptr<weld::Button> m_xButton; + /** StatusListener. Updates the button as the slot state changes */ + rtl::Reference<weld::WidgetStatusListener> m_xStatusListener; + OUString m_aCommand; + + DECL_LINK(CommandHdl, weld::Button&, void); + +public: + ExtraButton(weld::Container* pContainer, const OUString* pCommand) + : m_xBuilder(Application::CreateBuilder(pContainer, "sfx/ui/extrabutton.ui")) + , m_xContainer(m_xBuilder->weld_container("ExtraButton")) + , m_xButton(m_xBuilder->weld_button("button")) + { + if (pCommand) + { + m_aCommand = *pCommand; + m_xButton->connect_clicked(LINK(this, ExtraButton, CommandHdl)); + m_xStatusListener.set(new weld::WidgetStatusListener(m_xButton.get(), m_aCommand)); + m_xStatusListener->startListening(); + } + } + + ~ExtraButton() + { + if (m_xStatusListener.is()) + m_xStatusListener->dispose(); + } + + weld::Button& get_widget() { return *m_xButton; } +}; -void SfxCloseButton::setForegroundColor(const basegfx::BColor& rColor) +IMPL_LINK_NOARG(ExtraButton, CommandHdl, weld::Button&, void) { - m_aForegroundColor = rColor; + comphelper::dispatchCommand(m_aCommand, css::uno::Sequence<css::beans::PropertyValue>()); } -} // anonymous namespace - SfxInfoBarWindow::SfxInfoBarWindow(vcl::Window* pParent, const OUString& sId, const OUString& sPrimaryMessage, const OUString& sSecondaryMessage, InfobarType ibType, - WinBits nMessageStyle, bool bShowCloseButton) - : Window(pParent, WB_DIALOGCONTROL) + bool bShowCloseButton) + : InterimItemWindow(pParent, "sfx/ui/infobar.ui", "InfoBar") , m_sId(sId) , m_eType(ibType) - , m_pImage(VclPtr<FixedImage>::Create(this, nMessageStyle)) - , m_pPrimaryMessage(VclPtr<FixedText>::Create(this, nMessageStyle | WB_WORDBREAK)) - , m_pSecondaryMessage(VclPtr<FixedText>::Create(this, nMessageStyle | WB_WORDBREAK)) - , m_pCloseBtn(VclPtr<SfxCloseButton>::Create(this)) + , m_bLayingOut(false) + , m_xImage(m_xBuilder->weld_image("image")) + , m_xPrimaryMessage(m_xBuilder->weld_label("primary")) + , m_xSecondaryMessage(m_xBuilder->weld_text_view("secondary")) + , m_xButtonBox(m_xBuilder->weld_container("buttonbox")) + , m_xCloseBtn(m_xBuilder->weld_toolbar("closebar")) , m_aActionBtns() { - m_pCloseBtn->SetStyle(WB_DEFBUTTON | WB_TABSTOP); - SetForeAndBackgroundColors(m_eType); - float fScaleFactor = GetDPIScaleFactor(); - long nWidth = pParent->GetSizePixel().getWidth(); - SetPosSizePixel(Point(0, 0), Size(nWidth, INFO_BAR_BASE_HEIGHT * fScaleFactor)); + SetStyle(GetStyle() | WB_DIALOGCONTROL); - m_pImage->SetImage(Image(StockImage::Yes, GetInfoBarIconName(ibType))); - m_pImage->SetPaintTransparent(true); - m_pImage->Show(); + InitControlBase(m_xCloseBtn.get()); + + m_xImage->set_from_icon_name(GetInfoBarIconName(ibType)); + m_xSecondaryMessage->set_margin_top(m_xImage->get_preferred_size().Height() / 4); - vcl::Font aFont(m_pPrimaryMessage->GetControlFont()); - aFont.SetWeight(WEIGHT_BOLD); - m_pPrimaryMessage->SetControlFont(aFont); if (!sPrimaryMessage.isEmpty()) { - m_pPrimaryMessage->SetText(sPrimaryMessage); - m_pPrimaryMessage->Show(); + m_xPrimaryMessage->set_label(sPrimaryMessage); + m_xPrimaryMessage->show(); } - m_pSecondaryMessage->SetText(sSecondaryMessage); - m_pSecondaryMessage->Show(); + m_xSecondaryMessage->set_text(sSecondaryMessage); + m_aOrigMessageSize = m_xSecondaryMessage->get_preferred_size(); + m_aMessageSize = m_aOrigMessageSize; + m_xSecondaryMessage->connect_size_allocate(LINK(this, SfxInfoBarWindow, SizeAllocHdl)); if (bShowCloseButton) { - m_pCloseBtn->SetClickHdl(LINK(this, SfxInfoBarWindow, CloseHandler)); - m_pCloseBtn->Show(); + m_xCloseBtn->connect_clicked(LINK(this, SfxInfoBarWindow, CloseHandler)); + m_xCloseBtn->show(); } EnableChildTransparentMode(); - Resize(); -} + SetForeAndBackgroundColors(m_eType); + + auto nWidth = pParent->GetSizePixel().getWidth(); + auto nHeight = get_preferred_size().Height(); + SetSizePixel(Size(nWidth, nHeight + 2)); -void SfxInfoBarWindow::addButton(PushButton* pButton) -{ - pButton->SetParent(this); - pButton->Show(); - m_aActionBtns.emplace_back(pButton); Resize(); } -SfxInfoBarWindow::~SfxInfoBarWindow() { disposeOnce(); } - -void SfxInfoBarWindow::SetForeAndBackgroundColors(InfobarType eType) +IMPL_LINK(SfxInfoBarWindow, SizeAllocHdl, const Size&, rSize, void) { - basegfx::BColor aMessageColor; - GetInfoBarColors(eType, m_aBackgroundColor, m_aForegroundColor, aMessageColor); - - static_cast<SfxCloseButton*>(m_pCloseBtn.get())->setBackgroundColor(m_aBackgroundColor); - static_cast<SfxCloseButton*>(m_pCloseBtn.get())->setForegroundColor(m_aForegroundColor); - m_pPrimaryMessage->SetControlForeground(Color(aMessageColor)); - m_pSecondaryMessage->SetControlForeground(Color(aMessageColor)); + if (m_aMessageSize != rSize) + { + m_aMessageSize = rSize; + static_cast<SfxInfoBarContainerWindow*>(GetParent())->TriggerUpdateLayout(); + } } -void SfxInfoBarWindow::dispose() +Size SfxInfoBarWindow::DoLayout() { - for (auto& rxBtn : m_aActionBtns) - rxBtn.disposeAndClear(); - - m_pImage.disposeAndClear(); - m_pPrimaryMessage.disposeAndClear(); - m_pSecondaryMessage.disposeAndClear(); - m_pCloseBtn.disposeAndClear(); - m_aActionBtns.clear(); - vcl::Window::dispose(); + Size aGivenSize(GetSizePixel()); + + // disconnect SizeAllocHdl because we don't care about the size change + // during layout + m_xSecondaryMessage->connect_size_allocate(Link<const Size&, void>()); + + // blow away size cache in case m_aMessageSize.Width() is already the width request + // and we would get the cached preferred size instead of the recalc we want to force + m_xSecondaryMessage->set_size_request(-1, -1); + // make the width we were detected as set to by SizeAllocHdl as our desired width + m_xSecondaryMessage->set_size_request(m_aMessageSize.Width(), -1); + // get our preferred size with that message width + Size aSizeForWidth(aGivenSize.Width(), m_xContainer->get_preferred_size().Height()); + // restore the message preferred size so we can freely resize, and get a new + // m_aMessageSize and repeat the process if we do + m_xSecondaryMessage->set_size_request(m_aOrigMessageSize.Width(), -1); + + // connect SizeAllocHdl so changes outside of this layout will trigger a new layout + m_xSecondaryMessage->connect_size_allocate(LINK(this, SfxInfoBarWindow, SizeAllocHdl)); + + return aSizeForWidth; } -void SfxInfoBarWindow::Paint(vcl::RenderContext& rRenderContext, - const ::tools::Rectangle& rPaintRect) +void SfxInfoBarWindow::Layout() { - const ViewInformation2D aNewViewInfos; - const unique_ptr<BaseProcessor2D> pProcessor( - createBaseProcessor2DFromOutputDevice(rRenderContext, aNewViewInfos)); + if (m_bLayingOut) + return; + m_bLayingOut = true; - const ::tools::Rectangle aRect(Point(0, 0), PixelToLogic(GetSizePixel())); + InterimItemWindow::Layout(); - drawinglayer::primitive2d::Primitive2DContainer aSeq(2); - - // Light background - B2DPolygon aPolygon; - aPolygon.append(B2DPoint(aRect.Left(), aRect.Top())); - aPolygon.append(B2DPoint(aRect.Right(), aRect.Top())); - aPolygon.append(B2DPoint(aRect.Right(), aRect.Bottom())); - aPolygon.append(B2DPoint(aRect.Left(), aRect.Bottom())); - aPolygon.setClosed(true); - - PolyPolygonColorPrimitive2D* pBack - = new PolyPolygonColorPrimitive2D(B2DPolyPolygon(aPolygon), m_aBackgroundColor); - aSeq[0] = pBack; - - LineAttribute aLineAttribute(m_aForegroundColor, 1.0); - - // Bottom dark line - B2DPolygon aPolygonBottom; - aPolygonBottom.append(B2DPoint(aRect.Left(), aRect.Bottom())); - aPolygonBottom.append(B2DPoint(aRect.Right(), aRect.Bottom())); - - PolygonStrokePrimitive2D* pLineBottom - = new PolygonStrokePrimitive2D(aPolygonBottom, aLineAttribute); - - aSeq[1] = pLineBottom; - - pProcessor->process(aSeq); - - Window::Paint(rRenderContext, rPaintRect); + m_bLayingOut = false; } -void SfxInfoBarWindow::Resize() +weld::Button& SfxInfoBarWindow::addButton(const OUString* pCommand) { - float fScaleFactor = GetDPIScaleFactor(); + m_aActionBtns.emplace_back(std::make_unique<ExtraButton>(m_xButtonBox.get(), pCommand)); - long nWidth = GetSizePixel().getWidth(); - m_pCloseBtn->SetPosSizePixel(Point(nWidth - 25 * fScaleFactor, 15 * fScaleFactor), - Size(10 * fScaleFactor, 10 * fScaleFactor)); - - // Reparent the buttons and place them on the right of the bar - long nX = m_pCloseBtn->GetPosPixel().getX() - 15 * fScaleFactor; - long nButtonGap = 5 * fScaleFactor; - - for (auto const& actionBtn : m_aActionBtns) - { - long nButtonWidth = actionBtn->GetSizePixel().getWidth(); - nX -= nButtonWidth; - actionBtn->SetPosSizePixel(Point(nX, 5 * fScaleFactor), - Size(nButtonWidth, 30 * fScaleFactor)); - nX -= nButtonGap; - } + return m_aActionBtns.back()->get_widget(); +} - Point aPrimaryMessagePosition(32 * fScaleFactor + 10 * fScaleFactor, 10 * fScaleFactor); - Point aSecondaryMessagePosition(aPrimaryMessagePosition); - Size aMessageSize(nX - 35 * fScaleFactor, 20 * fScaleFactor); - Size aPrimaryTextSize = m_pPrimaryMessage->CalcMinimumSize(aMessageSize.getWidth()); - Size aSecondaryTextSize = m_pSecondaryMessage->CalcMinimumSize(aMessageSize.getWidth() - - aPrimaryTextSize.getWidth()); - if (!m_pPrimaryMessage->GetText().isEmpty()) - aSecondaryMessagePosition.AdjustX(aPrimaryTextSize.getWidth() + 6 * fScaleFactor); +SfxInfoBarWindow::~SfxInfoBarWindow() { disposeOnce(); } - long aMinimumHeight = std::max(m_pPrimaryMessage->CalcMinimumSize().getHeight(), - m_pSecondaryMessage->CalcMinimumSize().getHeight()); +void SfxInfoBarWindow::SetForeAndBackgroundColors(InfobarType eType) +{ + basegfx::BColor aMessageColor; + GetInfoBarColors(eType, m_aBackgroundColor, m_aForegroundColor, aMessageColor); - long aExtraHeight = aSecondaryTextSize.getHeight() - aMinimumHeight; + m_xPrimaryMessage->set_font_color(Color(aMessageColor)); + m_xSecondaryMessage->set_font_color(Color(aMessageColor)); - // The message won't be legible and the window will get too high - if (aMessageSize.getWidth() < 30) + Color aBackgroundColor(m_aBackgroundColor); + m_xPrimaryMessage->set_background(aBackgroundColor); + m_xSecondaryMessage->set_background(aBackgroundColor); + m_xContainer->set_background(aBackgroundColor); + if (m_xCloseBtn->get_visible()) { - aExtraHeight = 0; + m_xCloseBtn->set_background(aBackgroundColor); + SetCloseButtonImage(); } +} - m_pPrimaryMessage->SetPosSizePixel(aPrimaryMessagePosition, aPrimaryTextSize); - m_pSecondaryMessage->SetPosSizePixel(aSecondaryMessagePosition, aSecondaryTextSize); - m_pImage->SetPosSizePixel(Point(4, 4), Size(32 * fScaleFactor, 32 * fScaleFactor)); +void SfxInfoBarWindow::dispose() +{ + for (auto& rxBtn : m_aActionBtns) + rxBtn.reset(); - SetPosSizePixel(GetPosPixel(), Size(nWidth, INFO_BAR_BASE_HEIGHT * fScaleFactor - + aExtraHeight * fScaleFactor)); + m_xImage.reset(); + m_xPrimaryMessage.reset(); + m_xSecondaryMessage.reset(); + m_xButtonBox.reset(); + m_xCloseBtn.reset(); + m_aActionBtns.clear(); + InterimItemWindow::dispose(); } void SfxInfoBarWindow::Update(const OUString& sPrimaryMessage, const OUString& sSecondaryMessage, @@ -357,16 +338,16 @@ void SfxInfoBarWindow::Update(const OUString& sPrimaryMessage, const OUString& s { m_eType = eType; SetForeAndBackgroundColors(m_eType); - m_pImage->SetImage(Image(StockImage::Yes, GetInfoBarIconName(eType))); + m_xImage->set_from_icon_name(GetInfoBarIconName(eType)); } - m_pPrimaryMessage->SetText(sPrimaryMessage); - m_pSecondaryMessage->SetText(sSecondaryMessage); + m_xPrimaryMessage->set_label(sPrimaryMessage); + m_xSecondaryMessage->set_text(sSecondaryMessage); Resize(); Invalidate(); } -IMPL_LINK_NOARG(SfxInfoBarWindow, CloseHandler, Button*, void) +IMPL_LINK_NOARG(SfxInfoBarWindow, CloseHandler, const OString&, void) { static_cast<SfxInfoBarContainerWindow*>(GetParent())->removeInfoBar(this); } @@ -375,9 +356,15 @@ SfxInfoBarContainerWindow::SfxInfoBarContainerWindow(SfxInfoBarContainerChild* p : Window(pChildWin->GetParent(), WB_DIALOGCONTROL) , m_pChildWin(pChildWin) , m_pInfoBars() + , m_bResizing(false) { + m_aLayoutIdle.SetPriority(TaskPriority::HIGHEST); + m_aLayoutIdle.SetInvokeHandler(LINK(this, SfxInfoBarContainerWindow, DoUpdateLayout)); + m_aLayoutIdle.SetDebugName("SfxInfoBarContainerWindow m_aLayoutIdle"); } +IMPL_LINK_NOARG(SfxInfoBarContainerWindow, DoUpdateLayout, Timer*, void) { m_pChildWin->Update(); } + SfxInfoBarContainerWindow::~SfxInfoBarContainerWindow() { disposeOnce(); } void SfxInfoBarContainerWindow::dispose() @@ -388,16 +375,17 @@ void SfxInfoBarContainerWindow::dispose() Window::dispose(); } -VclPtr<SfxInfoBarWindow> -SfxInfoBarContainerWindow::appendInfoBar(const OUString& sId, const OUString& sPrimaryMessage, - const OUString& sSecondaryMessage, InfobarType ibType, - WinBits nMessageStyle, bool bShowCloseButton) +VclPtr<SfxInfoBarWindow> SfxInfoBarContainerWindow::appendInfoBar(const OUString& sId, + const OUString& sPrimaryMessage, + const OUString& sSecondaryMessage, + InfobarType ibType, + bool bShowCloseButton) { if (!isInfobarEnabled(sId)) return nullptr; auto pInfoBar = VclPtr<SfxInfoBarWindow>::Create(this, sId, sPrimaryMessage, sSecondaryMessage, - ibType, nMessageStyle, bShowCloseButton); + ibType, bShowCloseButton); basegfx::BColor aBackgroundColor; basegfx::BColor aForegroundColor; @@ -436,8 +424,6 @@ void SfxInfoBarContainerWindow::removeInfoBar(VclPtr<SfxInfoBarWindow> const& pI m_pInfoBars.erase(it); } - Resize(); - m_pChildWin->Update(); } @@ -457,25 +443,46 @@ bool SfxInfoBarContainerWindow::isInfobarEnabled(const OUString& sId) return true; } +// This triggers the SfxFrame to re-layout its childwindows +void SfxInfoBarContainerWindow::TriggerUpdateLayout() { m_aLayoutIdle.Start(); } + void SfxInfoBarContainerWindow::Resize() { - long nWidth = GetSizePixel().getWidth(); + if (m_bResizing) + return; + m_bResizing = true; + const Size& rOrigSize = GetSizePixel(); + auto nOrigWidth = rOrigSize.getWidth(); + auto nOrigHeight = rOrigSize.getHeight(); + long nHeight = 0; for (auto& rxInfoBar : m_pInfoBars) { - Size aSize = rxInfoBar->GetSizePixel(); - aSize.setWidth(nWidth); + Size aOrigSize = rxInfoBar->GetSizePixel(); + Size aSize(nOrigWidth, aOrigSize.Height()); + Point aPos(0, nHeight); + // stage 1: provisionally size the infobar, + rxInfoBar->SetPosSizePixel(aPos, aSize); + + // stage 2: perhaps allow height to stretch to fit + // the stage 1 width + aSize = rxInfoBar->DoLayout(); rxInfoBar->SetPosSizePixel(aPos, aSize); - rxInfoBar->Resize(); rxInfoBar->Show(); // Stretch to fit the infobar(s) nHeight += aSize.getHeight(); } - SetSizePixel(Size(nWidth, nHeight)); + if (nOrigHeight != nHeight) + { + SetSizePixel(Size(nOrigWidth, nHeight)); + TriggerUpdateLayout(); + } + + m_bResizing = false; } SFX_IMPL_POS_CHILDWINDOW_WITHID(SfxInfoBarContainerChild, SID_INFOBAR, SFX_OBJECTBAR_OBJECT); @@ -502,6 +509,15 @@ SfxChildWinInfo SfxInfoBarContainerChild::GetInfo() const void SfxInfoBarContainerChild::Update() { + // Layout to current width, this may change the height + if (vcl::Window* pChild = GetWindow()) + { + Size aSize(pChild->GetSizePixel()); + pChild->Resize(); + if (aSize == pChild->GetSizePixel()) + return; + } + // Refresh the frame to take the infobars container height change into account const sal_uInt16 nId = GetChildWindowId(); SfxViewFrame* pVFrame = m_pBindings->GetDispatcher()->GetFrame(); |