bump product version to 4.1.6.2
[LibreOffice.git] / sfx2 / source / sidebar / Deck.cxx
blob82713a716de24aaf97180aede5f21c81a1a258d8
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "Deck.hxx"
20 #include "DeckDescriptor.hxx"
21 #include "DeckLayouter.hxx"
22 #include "DrawHelper.hxx"
23 #include "DeckTitleBar.hxx"
24 #include "PanelTitleBar.hxx"
25 #include "Paint.hxx"
26 #include "Panel.hxx"
27 #include "ToolBoxBackground.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>
35 #include <boost/bind.hpp>
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
41 namespace sfx2 { namespace sidebar {
44 namespace {
45 static const sal_Int32 MinimalPanelHeight (25);
49 Deck::Deck (
50 const DeckDescriptor& rDeckDescriptor,
51 Window* pParentWindow,
52 const ::boost::function<void(void)>& rCloserAction)
53 : Window(pParentWindow, 0),
54 msId(rDeckDescriptor.msId),
55 maIcon(),
56 msIconURL(rDeckDescriptor.msIconURL),
57 msHighContrastIconURL(rDeckDescriptor.msHighContrastIconURL),
58 mnMinimalWidth(0),
59 maPanels(),
60 mpTitleBar(new DeckTitleBar(rDeckDescriptor.msTitle, this, rCloserAction)),
61 mpScrollClipWindow(new Window(this)),
62 mpScrollContainer(new ScrollContainerWindow(mpScrollClipWindow.get())),
63 mpFiller(new Window(this)),
64 mpVerticalScrollBar(new ScrollBar(this))
66 SetBackground(Wallpaper());
68 mpScrollClipWindow->SetBackground(Wallpaper());
69 mpScrollClipWindow->Show();
71 mpScrollContainer->SetStyle(mpScrollContainer->GetStyle() | WB_DIALOGCONTROL);
72 mpScrollContainer->SetBackground(Wallpaper());
73 mpScrollContainer->Show();
75 mpVerticalScrollBar->SetScrollHdl(LINK(this, Deck, HandleVerticalScrollBarChange));
77 #ifdef DEBUG
78 SetText(A2S("Deck"));
79 mpScrollClipWindow->SetText(A2S("ScrollClipWindow"));
80 mpFiller->SetText(A2S("Filler"));
81 mpVerticalScrollBar->SetText(A2S("VerticalScrollBar"));
82 #endif
88 Deck::~Deck (void)
90 Dispose();
92 // We have to explicitly trigger the destruction of panels.
93 // Otherwise that is done by one of our base class destructors
94 // without updating maPanels.
95 maPanels.clear();
101 void Deck::Dispose (void)
103 SharedPanelContainer aPanels;
104 aPanels.swap(maPanels);
105 for (SharedPanelContainer::iterator
106 iPanel(aPanels.begin()),
107 iEnd(aPanels.end());
108 iPanel!=iEnd;
109 ++iPanel)
111 if (*iPanel)
113 (*iPanel)->Dispose();
114 OSL_ASSERT(iPanel->unique());
115 iPanel->reset();
119 mpTitleBar.reset();
120 mpFiller.reset();
121 mpVerticalScrollBar.reset();
127 const ::rtl::OUString& Deck::GetId (void) const
129 return msId;
135 DeckTitleBar* Deck::GetTitleBar (void) const
137 return mpTitleBar.get();
143 Rectangle Deck::GetContentArea (void) const
145 const Size aWindowSize (GetSizePixel());
146 const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
148 return Rectangle(
149 Theme::GetInteger(Theme::Int_DeckLeftPadding) + nBorderSize,
150 Theme::GetInteger(Theme::Int_DeckTopPadding) + nBorderSize,
151 aWindowSize.Width() - 1 - Theme::GetInteger(Theme::Int_DeckRightPadding) - nBorderSize,
152 aWindowSize.Height() - 1 - Theme::GetInteger(Theme::Int_DeckBottomPadding) - nBorderSize);
158 ::rtl::OUString Deck::GetIconURL (const bool bIsHighContrastModeActive) const
160 if (bIsHighContrastModeActive)
161 return msHighContrastIconURL;
162 else
163 return msIconURL;
169 void Deck::Paint (const Rectangle& rUpdateArea)
171 (void) rUpdateArea;
173 const Size aWindowSize (GetSizePixel());
174 const SvBorder aPadding (
175 Theme::GetInteger(Theme::Int_DeckLeftPadding),
176 Theme::GetInteger(Theme::Int_DeckTopPadding),
177 Theme::GetInteger(Theme::Int_DeckRightPadding),
178 Theme::GetInteger(Theme::Int_DeckBottomPadding));
180 // Paint deck background outside the border.
181 Rectangle aBox(
184 aWindowSize.Width() - 1,
185 aWindowSize.Height() - 1);
186 DrawHelper::DrawBorder(
187 *this,
188 aBox,
189 aPadding,
190 Theme::GetPaint(Theme::Paint_DeckBackground),
191 Theme::GetPaint(Theme::Paint_DeckBackground));
193 // Paint the border.
194 const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
195 aBox.Left() += aPadding.Left();
196 aBox.Top() += aPadding.Top();
197 aBox.Right() -= aPadding.Right();
198 aBox.Bottom() -= aPadding.Bottom();
199 const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
200 DrawHelper::DrawBorder(
201 *this,
202 aBox,
203 SvBorder(nBorderSize, nBorderSize, nBorderSize, nBorderSize),
204 rHorizontalBorderPaint,
205 Theme::GetPaint(Theme::Paint_VerticalBorder));
211 void Deck::DataChanged (const DataChangedEvent& rEvent)
213 (void)rEvent;
214 RequestLayout();
220 long Deck::Notify (NotifyEvent& rEvent)
222 if (rEvent.GetType() == EVENT_COMMAND)
224 CommandEvent* pCommandEvent = reinterpret_cast<CommandEvent*>(rEvent.GetData());
225 if (pCommandEvent != NULL)
226 switch (pCommandEvent->GetCommand())
228 case COMMAND_WHEEL:
229 return ProcessWheelEvent(pCommandEvent, rEvent)
230 ? sal_True
231 : sal_False;
233 default:
234 break;
238 return Window::Notify(rEvent);
244 bool Deck::ProcessWheelEvent (
245 CommandEvent* pCommandEvent,
246 NotifyEvent& rEvent)
248 if ( ! mpVerticalScrollBar)
249 return false;
250 if ( ! mpVerticalScrollBar->IsVisible())
251 return false;
253 // Ignore all wheel commands from outside the vertical scroll bar.
254 // Otherwise after a scroll we might land on a spin field and
255 // subsequent wheel events would change the value of that control.
256 if (rEvent.GetWindow() != mpVerticalScrollBar.get())
257 return true;
259 // Get the wheel data and check that it describes a valid vertical
260 // scroll.
261 const CommandWheelData* pData = pCommandEvent->GetWheelData();
262 if (pData==NULL
263 || pData->GetModifier()
264 || pData->GetMode() != COMMAND_WHEEL_SCROLL
265 || pData->IsHorz())
266 return false;
268 // Execute the actual scroll action.
269 long nDelta = pData->GetDelta();
270 mpVerticalScrollBar->DoScroll(
271 mpVerticalScrollBar->GetThumbPos() - nDelta);
272 return true;
278 void Deck::SetPanels (const SharedPanelContainer& rPanels)
280 maPanels = rPanels;
282 RequestLayout();
288 const SharedPanelContainer& Deck::GetPanels (void) const
290 return maPanels;
296 void Deck::RequestLayout (void)
298 mnMinimalWidth = 0;
300 DeckLayouter::LayoutDeck(
301 GetContentArea(),
302 mnMinimalWidth,
303 maPanels,
304 *GetTitleBar(),
305 *mpScrollClipWindow,
306 *mpScrollContainer,
307 *mpFiller,
308 *mpVerticalScrollBar);
314 ::Window* Deck::GetPanelParentWindow (void)
316 return mpScrollContainer.get();
322 void Deck::ShowPanel (const Panel& rPanel)
324 if (mpVerticalScrollBar && mpVerticalScrollBar->IsVisible())
326 // Get vertical extent of the panel.
327 sal_Int32 nPanelTop (rPanel.GetPosPixel().Y());
328 const sal_Int32 nPanelBottom (nPanelTop + rPanel.GetSizePixel().Height() - 1);
329 // Add the title bar into the extent.
330 if (rPanel.GetTitleBar() != NULL && rPanel.GetTitleBar()->IsVisible())
331 nPanelTop = rPanel.GetTitleBar()->GetPosPixel().Y();
333 // Determine what the new thumb position should be like.
334 // When the whole panel does not fit then make its top visible
335 // and it off at the bottom.
336 sal_Int32 nNewThumbPos (mpVerticalScrollBar->GetThumbPos());
337 if (nPanelBottom >= nNewThumbPos+mpVerticalScrollBar->GetVisibleSize())
338 nNewThumbPos = nPanelBottom - mpVerticalScrollBar->GetVisibleSize();
339 if (nPanelTop < nNewThumbPos)
340 nNewThumbPos = nPanelTop;
342 mpVerticalScrollBar->SetThumbPos(nNewThumbPos);
343 mpScrollContainer->SetPosPixel(
344 Point(
345 mpScrollContainer->GetPosPixel().X(),
346 -nNewThumbPos));
354 const char* GetWindowClassification (const Window* pWindow)
356 const String& rsName (pWindow->GetText());
357 if (rsName.Len() > 0)
359 return ::rtl::OUStringToOString(rsName, RTL_TEXTENCODING_ASCII_US).getStr();
361 else
363 static char msWindow[] = "window";
364 return msWindow;
369 void Deck::PrintWindowSubTree (Window* pRoot, int nIndentation)
371 static const char* sIndentation = " ";
372 const Point aLocation (pRoot->GetPosPixel());
373 const Size aSize (pRoot->GetSizePixel());
374 const char* sClassification = GetWindowClassification(pRoot);
375 const char* sVisible = pRoot->IsVisible() ? "visible" : "hidden";
376 OSL_TRACE("%s%x %s %s +%d+%d x%dx%d",
377 sIndentation+strlen(sIndentation)-nIndentation*4,
378 pRoot,
379 sClassification,
380 sVisible,
381 aLocation.X(),aLocation.Y(),
382 aSize.Width(),aSize.Height());
384 const sal_uInt16 nChildCount (pRoot->GetChildCount());
385 for (sal_uInt16 nIndex=0; nIndex<nChildCount; ++nIndex)
386 PrintWindowSubTree(pRoot->GetChild(nIndex), nIndentation+1);
392 void Deck::PrintWindowTree (void)
394 PrintWindowSubTree(this, 0);
400 void Deck::PrintWindowTree (const ::std::vector<Panel*>& rPanels)
402 (void)rPanels;
404 PrintWindowTree();
410 IMPL_LINK(Deck, HandleVerticalScrollBarChange,void*, EMPTYARG)
412 const sal_Int32 nYOffset (-mpVerticalScrollBar->GetThumbPos());
413 mpScrollContainer->SetPosPixel(
414 Point(
415 mpScrollContainer->GetPosPixel().X(),
416 nYOffset));
417 return sal_True;
423 //----- Deck::ScrollContainerWindow -------------------------------------------
425 Deck::ScrollContainerWindow::ScrollContainerWindow (Window* pParentWindow)
426 : Window(pParentWindow),
427 maSeparators()
429 #ifdef DEBUG
430 SetText(A2S("ScrollContainerWindow"));
431 #endif
437 Deck::ScrollContainerWindow::~ScrollContainerWindow (void)
444 void Deck::ScrollContainerWindow::Paint (const Rectangle& rUpdateArea)
446 (void)rUpdateArea;
448 // Paint the separators.
449 const sal_Int32 nSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
450 const sal_Int32 nLeft (0);
451 const sal_Int32 nRight (GetSizePixel().Width()-1);
452 const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
453 for (::std::vector<sal_Int32>::const_iterator iY(maSeparators.begin()), iEnd(maSeparators.end());
454 iY!=iEnd;
455 ++iY)
457 DrawHelper::DrawHorizontalLine(
458 *this,
459 nLeft,
460 nRight,
461 *iY,
462 nSeparatorHeight,
463 rHorizontalBorderPaint);
470 void Deck::ScrollContainerWindow::SetSeparators (const ::std::vector<sal_Int32>& rSeparators)
472 maSeparators = rSeparators;
476 } } // end of namespace sfx2::sidebar