1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/builderfactory.hxx>
21 #include <vcl/button.hxx>
22 #include <vcl/layout.hxx>
23 #include <bitmaps.hlst>
24 #include "PriorityHBox.hxx"
25 #include "NotebookbarPopup.hxx"
26 #include <sfx2/viewfrm.hxx>
28 #define DUMMY_WIDTH 50
29 #define BUTTON_WIDTH 30
32 * PriorityMergedHBox is a VclHBox which hides its own children if there is no sufficient space.
37 class PriorityMergedHBox
: public PriorityHBox
40 VclPtr
<PushButton
> m_pButton
;
41 VclPtr
<NotebookbarPopup
> m_pPopup
;
43 DECL_LINK(PBClickHdl
, Button
*, void);
46 explicit PriorityMergedHBox(vcl::Window
* pParent
)
47 : PriorityHBox(pParent
)
49 m_pButton
= VclPtr
<PushButton
>::Create(this, WB_FLATBUTTON
);
50 m_pButton
->SetClickHdl(LINK(this, PriorityMergedHBox
, PBClickHdl
));
51 m_pButton
->SetModeImage(Image(StockImage::Yes
, CHEVRON
));
52 m_pButton
->set_width_request(25);
53 m_pButton
->set_pack_type(VclPackType::End
);
57 virtual ~PriorityMergedHBox() override
{ disposeOnce(); }
59 virtual void Resize() override
61 if (!m_bInitialized
&& SfxViewFrame::Current())
66 return VclHBox::Resize();
69 tools::Long nWidth
= GetSizePixel().Width();
70 tools::Long nCurrentWidth
= VclHBox::calculateRequisition().getWidth() + BUTTON_WIDTH
;
72 // Hide lower priority controls
73 for (int i
= GetChildCount() - 1; i
>= 0; i
--)
75 vcl::Window
* pWindow
= GetChild(i
);
77 if (nCurrentWidth
<= nWidth
)
80 if (pWindow
&& pWindow
->GetParent() == this && pWindow
->IsVisible())
82 if (pWindow
->GetOutputWidthPixel())
83 nCurrentWidth
-= pWindow
->GetOutputWidthPixel();
85 nCurrentWidth
-= DUMMY_WIDTH
;
90 // Show higher priority controls if we already have enough space
91 for (int i
= 0; i
< GetChildCount(); i
++)
93 vcl::Window
* pWindow
= GetChild(i
);
95 if (pWindow
->GetParent() != this)
100 if (pWindow
&& !pWindow
->IsVisible())
103 nCurrentWidth
+= getLayoutRequisition(*pWindow
).Width() + get_spacing();
105 if (nCurrentWidth
> nWidth
)
115 if (GetHiddenCount())
121 virtual void dispose() override
123 m_pButton
.disposeAndClear();
125 m_pPopup
.disposeAndClear();
126 PriorityHBox::dispose();
129 int GetHiddenCount() const override
133 for (int i
= GetChildCount() - 1; i
>= 0; i
--)
135 vcl::Window
* pWindow
= GetChild(i
);
136 if (pWindow
&& pWindow
->GetParent() == this && !pWindow
->IsVisible())
143 Size
calculateRequisition() const override
147 return VclHBox::calculateRequisition();
150 sal_uInt16 nVisibleChildren
= 0;
153 for (vcl::Window
* pChild
= GetWindow(GetWindowType::FirstChild
); pChild
;
154 pChild
= pChild
->GetWindow(GetWindowType::Next
))
156 if (!pChild
->IsVisible())
159 Size aChildSize
= getLayoutRequisition(*pChild
);
161 tools::Long nPrimaryDimension
= getPrimaryDimension(aChildSize
);
162 nPrimaryDimension
+= pChild
->get_padding() * 2;
163 setPrimaryDimension(aChildSize
, nPrimaryDimension
);
165 accumulateMaxes(aChildSize
, aSize
);
168 setPrimaryDimension(aSize
, 200);
169 return finalizeMaxes(aSize
, nVisibleChildren
);
172 void GetChildrenWithPriorities() override
{};
176 IMPL_LINK(PriorityMergedHBox
, PBClickHdl
, Button
*, /*pButton*/, void)
179 m_pPopup
.disposeAndClear();
181 m_pPopup
= VclPtr
<NotebookbarPopup
>::Create(this);
183 for (int i
= 0; i
< GetChildCount(); i
++)
185 vcl::Window
* pWindow
= GetChild(i
);
186 if (pWindow
!= m_pButton
)
188 if (!pWindow
->IsVisible())
191 pWindow
->SetParent(m_pPopup
->getBox());
192 // count is decreased because we moved child
198 m_pPopup
->hideSeparators(true);
200 tools::Long x
= m_pButton
->GetPosPixel().getX();
201 tools::Long y
= m_pButton
->GetPosPixel().getY() + GetSizePixel().Height();
202 tools::Rectangle
aRect(x
, y
, x
, y
);
204 m_pPopup
->StartPopupMode(aRect
, FloatWinPopupFlags::Down
| FloatWinPopupFlags::GrabFocus
205 | FloatWinPopupFlags::AllMouseButtonClose
);
208 VCL_BUILDER_FACTORY(PriorityMergedHBox
)
210 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */