29#include <osl/diagnose.h>
33#include <com/sun/star/uno/Reference.hxx>
34#include <com/sun/star/frame/Desktop.hpp>
35#include <com/sun/star/frame/XDesktop2.hpp>
36#include <com/sun/star/frame/XFrame.hpp>
37#include <com/sun/star/ui/XSidebarPanel.hpp>
42using namespace css::uno;
47 const sal_Int32 MinimalPanelHeight (25);
64 LayoutItem(std::shared_ptr<Panel> pPanel)
75 sal_Int32& rMinimalWidth,
76 sal_Int32& rMinimalHeight,
77 ::std::vector<LayoutItem>& rLayoutItems,
79 const bool bShowVerticalScrollBar);
80 void GetRequestedSizes (
81 ::std::vector<LayoutItem>& rLayoutItem,
82 sal_Int32& rAvailableHeight,
83 sal_Int32& rMinimalWidth,
85 void DistributeHeights (
86 ::std::vector<LayoutItem>& rLayoutItems,
87 const sal_Int32 nHeightToDistribute,
88 const sal_Int32 nContainerHeight,
89 const bool bMinimumHeightIsBase);
90 sal_Int32 PlacePanels (
91 ::std::vector<LayoutItem>& rLayoutItems,
92 const LayoutMode eMode_);
94 const SidebarDockingWindow* pDockingWindow,
95 DeckTitleBar& rTitleBar,
100 const bool bShowVerticalScrollBar);
101 void SetupVerticalScrollBar(
103 const sal_Int32 nContentHeight,
104 const sal_Int32 nVisibleHeight);
110 sal_Int32& rMinimalWidth,
111 sal_Int32& rMinimalHeight,
118 tools::Rectangle aBox(PlaceDeckTitle(pDockingWindow, rDeckTitleBar, rContentArea));
120 if ( rPanels.empty())
124 ::std::vector<LayoutItem> aLayoutItems;
125 aLayoutItems.reserve(rPanels.size());
126 for (
auto& rPanel : rPanels)
127 aLayoutItems.emplace_back(rPanel);
142 sal_Int32& rMinimalWidth,
143 sal_Int32& rMinimalHeight,
144 ::std::vector<LayoutItem>& rLayoutItems,
146 const bool bShowVerticalScrollBar)
148 tools::Rectangle aBox (PlaceVerticalScrollBar(rVerticalScrollBar, rContentArea, bShowVerticalScrollBar));
153 sal_Int32 nAvailableHeight (aBox.GetHeight());
154 GetRequestedSizes(rLayoutItems, nAvailableHeight, rMinimalWidth, aBox);
155 const sal_Int32 nTotalDecorationHeight (aBox.GetHeight() - nAvailableHeight);
160 sal_Int32 nTotalPreferredHeight (0);
161 sal_Int32 nTotalMinimumHeight (0);
163 for (
const auto& rItem : rLayoutItems)
165 nTotalMinimumHeight += rItem.maLayoutSize.Minimum;
166 nTotalPreferredHeight += rItem.maLayoutSize.Preferred;
169 if (nTotalMinimumHeight > nAvailableHeight && !bShowVerticalScrollBar
196 LayoutMode
eMode(MinimumOrLarger);
197 if (bShowVerticalScrollBar)
201 const sal_Int32 nContentHeight(nTotalPreferredHeight + nTotalDecorationHeight);
202 SetupVerticalScrollBar(rVerticalScrollBar, nContentHeight, aBox.GetHeight());
206 if (nTotalPreferredHeight <= nAvailableHeight)
207 eMode = PreferredOrLarger;
209 eMode = MinimumOrLarger;
211 const sal_Int32 nTotalHeight (eMode==MinimumOrLarger ? nTotalMinimumHeight : nTotalPreferredHeight);
215 nAvailableHeight-nTotalHeight,
217 eMode==MinimumOrLarger);
220 const sal_Int32 nUsedHeight(PlacePanels(rLayoutItems, eMode));
221 rMinimalHeight = nUsedHeight;
224sal_Int32 PlacePanels (
225 ::std::vector<LayoutItem>& rLayoutItems,
226 const LayoutMode eMode)
232 for(::std::vector<LayoutItem>::const_iterator iItem(rLayoutItems.begin()),
233 iEnd(rLayoutItems.end());
240 Panel& rPanel (*iItem->mpPanel);
242 rPanel.set_margin_top(nDeckSeparatorHeight);
243 rPanel.set_margin_bottom(0);
246 if (!rPanel.IsLurking())
248 nY += nDeckSeparatorHeight;
251 bool bShowTitlebar = iItem->mbShowTitleBar;
252 PanelTitleBar* pTitleBar = rPanel.GetTitleBar();
253 pTitleBar->Show(bShowTitlebar);
254 rPanel.set_vexpand(!bShowTitlebar);
258 bool bExpanded = rPanel.IsExpanded() && !rPanel.IsLurking();
259 if (bShowTitlebar || bExpanded)
263 sal_Int32 nPanelHeight(0);
270 case MinimumOrLarger:
271 nPanelHeight = iItem->maLayoutSize.Minimum + iItem->mnDistributedHeight;
273 case PreferredOrLarger:
274 nPanelHeight = iItem->maLayoutSize.Preferred + iItem->mnDistributedHeight;
277 nPanelHeight = iItem->maLayoutSize.Preferred;
285 nPanelHeight += pTitleBar->get_preferred_size().Height();
287 rPanel.SetHeightPixel(nPanelHeight);
300 if (iItem == rLayoutItems.end()-1)
303 rPanel.set_margin_bottom(nDeckSeparatorHeight);
304 nY += nDeckSeparatorHeight;
312void GetRequestedSizes (
313 ::std::vector<LayoutItem>& rLayoutItems,
314 sal_Int32& rAvailableHeight,
315 sal_Int32& rMinimalWidth,
318 rAvailableHeight = rContentBox.
GetHeight();
322 for (
auto& rItem : rLayoutItems)
324 rItem.maLayoutSize = ui::LayoutSize(0,0,0);
326 if (rItem.mpPanel ==
nullptr)
329 if (rItem.mpPanel->IsLurking())
331 rItem.mbShowTitleBar =
false;
335 if (rLayoutItems.size() == 1
336 && rItem.mpPanel->IsTitleBarOptional())
340 rAvailableHeight -= nDeckSeparatorHeight;
341 rItem.mbShowTitleBar =
false;
347 PanelTitleBar* pTitleBar = rItem.mpPanel->GetTitleBar();
348 const sal_Int32 nPanelTitleBarHeight = pTitleBar->get_preferred_size().Height();
350 rAvailableHeight -= nPanelTitleBarHeight;
351 rAvailableHeight -= nDeckSeparatorHeight;
354 if (rItem.mpPanel->IsExpanded() && rItem.mpPanel->GetPanelComponent().is())
356 Reference<ui::XSidebarPanel> xPanel (rItem.mpPanel->GetPanelComponent());
358 rItem.maLayoutSize = xPanel->getHeightForWidth(rContentBox.
GetWidth());
359 if (!(0 <= rItem.maLayoutSize.Minimum && rItem.maLayoutSize.Minimum <= rItem.maLayoutSize.Preferred
360 && rItem.maLayoutSize.Preferred <= rItem.maLayoutSize.Maximum))
362 SAL_INFO(
"sfx.sidebar",
"Please follow LayoutSize constraints: 0 ≤ "
363 "Minimum ≤ Preferred ≤ Maximum."
364 " Currently: Minimum: "
365 << rItem.maLayoutSize.Minimum
366 <<
" Preferred: " << rItem.maLayoutSize.Preferred
367 <<
" Maximum: " << rItem.maLayoutSize.Maximum);
370 sal_Int32 nWidth = rMinimalWidth;
375 nWidth = xPanel->getMinimalWidth();
381 uno::Reference<frame::XDesktop2> xDesktop
383 uno::Reference<frame::XFrame>
xFrame = xDesktop->getActiveFrame();
386 SidebarController* pController
388 if (pController && pController->getMaximumWidth() < nWidth)
392 pController->setMaximumWidth(nWidth + 100);
396 if (nWidth > rMinimalWidth)
397 rMinimalWidth = nWidth;
400 rItem.maLayoutSize = ui::LayoutSize(MinimalPanelHeight, -1, 0);
404void DistributeHeights (
405 ::std::vector<LayoutItem>& rLayoutItems,
406 const sal_Int32 nHeightToDistribute,
407 const sal_Int32 nContainerHeight,
408 const bool bMinimumHeightIsBase)
410 if (nHeightToDistribute <= 0)
413 sal_Int32 nRemainingHeightToDistribute (nHeightToDistribute);
417 sal_Int32 nTotalWeight (0);
418 sal_Int32 nNoMaximumCount (0);
420 for (
auto& rItem : rLayoutItems)
422 if (rItem.maLayoutSize.Maximum == 0)
424 if (rItem.maLayoutSize.Maximum < 0)
427 const sal_Int32 nBaseHeight (
429 ? rItem.maLayoutSize.Minimum
430 : rItem.maLayoutSize.Preferred);
431 if (nBaseHeight < nContainerHeight)
433 rItem.mnWeight = nContainerHeight - nBaseHeight;
434 nTotalWeight += rItem.mnWeight;
438 if (nTotalWeight == 0)
442 for (
auto& rItem : rLayoutItems)
444 const sal_Int32 nBaseHeight (
446 ? rItem.maLayoutSize.Minimum
447 : rItem.maLayoutSize.Preferred);
448 sal_Int32 nDistributedHeight (rItem.mnWeight * nHeightToDistribute / nTotalWeight);
449 if (nBaseHeight+nDistributedHeight > rItem.maLayoutSize.Maximum
450 && rItem.maLayoutSize.Maximum >= 0)
452 nDistributedHeight = ::std::max<sal_Int32>(0, rItem.maLayoutSize.Maximum - nBaseHeight);
454 rItem.mnDistributedHeight = nDistributedHeight;
455 nRemainingHeightToDistribute -= nDistributedHeight;
458 if (nRemainingHeightToDistribute == 0)
460 OSL_ASSERT(nRemainingHeightToDistribute > 0);
466 if (nNoMaximumCount == 0)
472 const sal_Int32 nAdditionalHeightPerPanel(nRemainingHeightToDistribute / nNoMaximumCount);
474 sal_Int32 nAdditionalHeightForFirstPanel (nRemainingHeightToDistribute
475 - nNoMaximumCount*nAdditionalHeightPerPanel);
477 for (
auto& rItem : rLayoutItems)
479 if (rItem.maLayoutSize.Maximum < 0)
481 rItem.mnDistributedHeight += nAdditionalHeightPerPanel + nAdditionalHeightForFirstPanel;
482 nRemainingHeightToDistribute -= nAdditionalHeightPerPanel + nAdditionalHeightForFirstPanel;
486 OSL_ASSERT(nRemainingHeightToDistribute==0);
490 const SidebarDockingWindow* pDockingWindow,
491 DeckTitleBar& rDeckTitleBar,
494 if (pDockingWindow->IsFloatingMode())
497 rDeckTitleBar.Show(
false);
498 return rAvailableSpace;
502 rDeckTitleBar.Show(
true);
503 const sal_Int32 nDeckTitleBarHeight(rDeckTitleBar.get_preferred_size().Height());
505 rAvailableSpace.
Left(),
506 rAvailableSpace.
Top() + nDeckTitleBarHeight,
507 rAvailableSpace.
Right(),
508 rAvailableSpace.
Bottom());
515 const bool bShowVerticalScrollBar)
517 if (bShowVerticalScrollBar)
520 rVerticalScrollBar.
set_vpolicy(VclPolicyType::ALWAYS);
522 rAvailableSpace.
Left(),
523 rAvailableSpace.
Top(),
524 rAvailableSpace.
Right() - nScrollBarWidth,
525 rAvailableSpace.
Bottom());
529 rVerticalScrollBar.
set_vpolicy(VclPolicyType::NEVER);
530 return rAvailableSpace;
534void SetupVerticalScrollBar(
536 const sal_Int32 nContentHeight,
537 const sal_Int32 nVisibleHeight)
539 OSL_ASSERT(nContentHeight > nVisibleHeight);
css::ui::LayoutSize maLayoutSize
sal_Int32 mnDistributedHeight
std::shared_ptr< Panel > mpPanel
#define SAL_INFO(area, stream)
Reference< XComponentContext > getProcessComponentContext()
Reference< XFrame > xFrame