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 .
21 #include "DeckDescriptor.hxx"
22 #include "DeckLayouter.hxx"
23 #include "DrawHelper.hxx"
24 #include "DeckTitleBar.hxx"
25 #include "PanelTitleBar.hxx"
28 #include <sfx2/sidebar/Tools.hxx>
29 #include <sfx2/sidebar/Theme.hxx>
31 #include <vcl/dockwin.hxx>
32 #include <vcl/scrbar.hxx>
33 #include <tools/svborder.hxx>
36 using namespace css::uno
;
38 namespace sfx2
{ namespace sidebar
{
40 Deck::Deck(const DeckDescriptor
& rDeckDescriptor
, vcl::Window
* pParentWindow
,
41 const std::function
<void()>& rCloserAction
)
42 : Window(pParentWindow
, 0)
43 , msId(rDeckDescriptor
.msId
)
47 , mpTitleBar(VclPtr
<DeckTitleBar
>::Create(rDeckDescriptor
.msTitle
, this, rCloserAction
))
48 , mpScrollClipWindow(VclPtr
<vcl::Window
>::Create(this))
49 , mpScrollContainer(VclPtr
<ScrollContainerWindow
>::Create(mpScrollClipWindow
.get()))
50 , mpFiller(VclPtr
<vcl::Window
>::Create(this))
51 , mpVerticalScrollBar(VclPtr
<ScrollBar
>::Create(this))
53 mpScrollClipWindow
->SetBackground(Wallpaper());
54 mpScrollClipWindow
->Show();
56 mpScrollContainer
->SetStyle(mpScrollContainer
->GetStyle() | WB_DIALOGCONTROL
);
57 mpScrollContainer
->SetBackground(Wallpaper());
58 mpScrollContainer
->Show();
60 mpVerticalScrollBar
->SetScrollHdl(LINK(this, Deck
, HandleVerticalScrollBarChange
));
63 SetText(OUString("Deck"));
64 mpScrollClipWindow
->SetText(OUString("ScrollClipWindow"));
65 mpFiller
->SetText(OUString("Filler"));
66 mpVerticalScrollBar
->SetText(OUString("VerticalScrollBar"));
77 SharedPanelContainer aPanels
;
78 aPanels
.swap(maPanels
);
80 // We have to explicitly trigger the destruction of panels.
81 // Otherwise that is done by one of our base class destructors
82 // without updating maPanels.
83 for (size_t i
= 0; i
< aPanels
.size(); i
++)
84 aPanels
[i
].disposeAndClear();
86 mpTitleBar
.disposeAndClear();
87 mpFiller
.disposeAndClear();
88 mpVerticalScrollBar
.disposeAndClear();
89 mpScrollContainer
.disposeAndClear();
90 mpScrollClipWindow
.disposeAndClear();
92 vcl::Window::dispose();
95 DeckTitleBar
* Deck::GetTitleBar() const
97 return mpTitleBar
.get();
100 Rectangle
Deck::GetContentArea() const
102 const Size
aWindowSize (GetSizePixel());
103 const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize
));
106 Theme::GetInteger(Theme::Int_DeckLeftPadding
) + nBorderSize
,
107 Theme::GetInteger(Theme::Int_DeckTopPadding
) + nBorderSize
,
108 aWindowSize
.Width() - 1 - Theme::GetInteger(Theme::Int_DeckRightPadding
) - nBorderSize
,
109 aWindowSize
.Height() - 1 - Theme::GetInteger(Theme::Int_DeckBottomPadding
) - nBorderSize
);
112 void Deck::ApplySettings(vcl::RenderContext
& rRenderContext
)
114 rRenderContext
.SetBackground(Wallpaper());
117 void Deck::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& /*rUpdateArea*/)
119 const Size
aWindowSize (GetSizePixel());
120 const SvBorder
aPadding(Theme::GetInteger(Theme::Int_DeckLeftPadding
),
121 Theme::GetInteger(Theme::Int_DeckTopPadding
),
122 Theme::GetInteger(Theme::Int_DeckRightPadding
),
123 Theme::GetInteger(Theme::Int_DeckBottomPadding
));
125 // Paint deck background outside the border.
126 Rectangle
aBox(0, 0, aWindowSize
.Width() - 1, aWindowSize
.Height() - 1);
127 DrawHelper::DrawBorder(rRenderContext
, aBox
, aPadding
,
128 Theme::GetPaint(Theme::Paint_DeckBackground
),
129 Theme::GetPaint(Theme::Paint_DeckBackground
));
132 const int nBorderSize(Theme::GetInteger(Theme::Int_DeckBorderSize
));
133 aBox
.Left() += aPadding
.Left();
134 aBox
.Top() += aPadding
.Top();
135 aBox
.Right() -= aPadding
.Right();
136 aBox
.Bottom() -= aPadding
.Bottom();
137 const sfx2::sidebar::Paint
& rHorizontalBorderPaint(Theme::GetPaint(Theme::Paint_HorizontalBorder
));
138 DrawHelper::DrawBorder(rRenderContext
, aBox
,
139 SvBorder(nBorderSize
, nBorderSize
, nBorderSize
, nBorderSize
),
140 rHorizontalBorderPaint
,
141 Theme::GetPaint(Theme::Paint_VerticalBorder
));
144 void Deck::DataChanged (const DataChangedEvent
& rEvent
)
150 bool Deck::Notify (NotifyEvent
& rEvent
)
152 if (rEvent
.GetType() == MouseNotifyEvent::COMMAND
)
154 CommandEvent
* pCommandEvent
= static_cast<CommandEvent
*>(rEvent
.GetData());
155 if (pCommandEvent
!= NULL
)
156 switch (pCommandEvent
->GetCommand())
158 case CommandEventId::Wheel
:
159 return ProcessWheelEvent(pCommandEvent
);
166 return Window::Notify(rEvent
);
169 bool Deck::ProcessWheelEvent(CommandEvent
* pCommandEvent
)
171 if ( ! mpVerticalScrollBar
)
173 if ( ! mpVerticalScrollBar
->IsVisible())
176 // Get the wheel data and check that it describes a valid vertical
178 const CommandWheelData
* pData
= pCommandEvent
->GetWheelData();
180 || pData
->GetModifier()
181 || pData
->GetMode() != CommandWheelMode::SCROLL
185 // Execute the actual scroll action.
186 long nDelta
= pData
->GetDelta();
187 mpVerticalScrollBar
->DoScroll(
188 mpVerticalScrollBar
->GetThumbPos() - nDelta
);
193 * This container may contain existing panels that are
194 * being re-used, and new ones too.
196 void Deck::ResetPanels(const SharedPanelContainer
& rPanels
)
198 // First dispose old panels we no longer need.
199 for (size_t i
= 0; i
< maPanels
.size(); i
++)
202 for (size_t j
= 0; j
< rPanels
.size(); j
++)
203 bFound
= bFound
|| (maPanels
[i
].get() == rPanels
[j
].get());
204 if (!bFound
) // this one didn't survive.
205 maPanels
[i
].disposeAndClear();
212 void Deck::RequestLayout()
216 DeckLayouter::LayoutDeck(GetContentArea(), mnMinimalWidth
, maPanels
,
217 *GetTitleBar(), *mpScrollClipWindow
, *mpScrollContainer
,
218 *mpFiller
, *mpVerticalScrollBar
);
221 vcl::Window
* Deck::GetPanelParentWindow()
223 return mpScrollContainer
.get();
226 void Deck::ShowPanel(const Panel
& rPanel
)
228 if (mpVerticalScrollBar
&& mpVerticalScrollBar
->IsVisible())
230 // Get vertical extent of the panel.
231 sal_Int32
nPanelTop (rPanel
.GetPosPixel().Y());
232 const sal_Int32
nPanelBottom (nPanelTop
+ rPanel
.GetSizePixel().Height() - 1);
233 // Add the title bar into the extent.
234 if (rPanel
.GetTitleBar() != NULL
&& rPanel
.GetTitleBar()->IsVisible())
235 nPanelTop
= rPanel
.GetTitleBar()->GetPosPixel().Y();
237 // Determine what the new thumb position should be like.
238 // When the whole panel does not fit then make its top visible
239 // and it off at the bottom.
240 sal_Int32
nNewThumbPos (mpVerticalScrollBar
->GetThumbPos());
241 if (nPanelBottom
>= nNewThumbPos
+mpVerticalScrollBar
->GetVisibleSize())
242 nNewThumbPos
= nPanelBottom
- mpVerticalScrollBar
->GetVisibleSize();
243 if (nPanelTop
< nNewThumbPos
)
244 nNewThumbPos
= nPanelTop
;
246 mpVerticalScrollBar
->SetThumbPos(nNewThumbPos
);
247 mpScrollContainer
->SetPosPixel(
249 mpScrollContainer
->GetPosPixel().X(),
255 const OUString
GetWindowClassification(const vcl::Window
* pWindow
)
257 const OUString
& rsName (pWindow
->GetText());
258 if (!rsName
.isEmpty())
264 return OUString("window");
268 void Deck::PrintWindowSubTree(vcl::Window
* pRoot
, int nIndentation
)
270 static const char* sIndentation
= " ";
271 const Point
aLocation (pRoot
->GetPosPixel());
272 const Size
aSize (pRoot
->GetSizePixel());
275 sIndentation
+ strlen(sIndentation
) - nIndentation
* 4 << pRoot
<< " "
276 << GetWindowClassification(pRoot
) << " "
277 << (pRoot
->IsVisible() ? "visible" : "hidden") << " +"
278 << aLocation
.X() << "+" << aLocation
.Y() << " x" << aSize
.Width()
279 << "x" << aSize
.Height());
281 const sal_uInt16
nChildCount(pRoot
->GetChildCount());
282 for (sal_uInt16 nIndex
= 0; nIndex
< nChildCount
; ++nIndex
)
283 PrintWindowSubTree(pRoot
->GetChild(nIndex
), nIndentation
+ 1);
286 IMPL_LINK_NOARG(Deck
, HandleVerticalScrollBarChange
)
288 const sal_Int32
nYOffset (-mpVerticalScrollBar
->GetThumbPos());
289 mpScrollContainer
->SetPosPixel(Point(mpScrollContainer
->GetPosPixel().X(),
291 return sal_IntPtr(true);
294 //----- Deck::ScrollContainerWindow -------------------------------------------
296 Deck::ScrollContainerWindow::ScrollContainerWindow (vcl::Window
* pParentWindow
)
297 : Window(pParentWindow
),
301 SetText(OUString("ScrollContainerWindow"));
305 void Deck::ScrollContainerWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& /*rUpdateArea*/)
307 // Paint the separators.
308 const sal_Int32
nSeparatorHeight(Theme::GetInteger(Theme::Int_DeckSeparatorHeight
));
309 const sal_Int32
nLeft(0);
310 const sal_Int32
nRight(GetSizePixel().Width() - 1);
311 const sfx2::sidebar::Paint
& rHorizontalBorderPaint(Theme::GetPaint(Theme::Paint_HorizontalBorder
));
312 for (std::vector
<sal_Int32
>::const_iterator
iY(maSeparators
.begin()); iY
!= maSeparators
.end(); ++iY
)
314 DrawHelper::DrawHorizontalLine(rRenderContext
, nLeft
, nRight
, *iY
,
315 nSeparatorHeight
, rHorizontalBorderPaint
);
319 void Deck::ScrollContainerWindow::SetSeparators (const ::std::vector
<sal_Int32
>& rSeparators
)
321 maSeparators
= rSeparators
;
324 } } // end of namespace sfx2::sidebar
326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */