Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "Deck.hxx"
21 : #include "DeckDescriptor.hxx"
22 : #include "DeckLayouter.hxx"
23 : #include "DrawHelper.hxx"
24 : #include "DeckTitleBar.hxx"
25 : #include "PanelTitleBar.hxx"
26 : #include "Paint.hxx"
27 : #include "Panel.hxx"
28 : #include <sfx2/sidebar/Tools.hxx>
29 : #include <sfx2/sidebar/Theme.hxx>
30 :
31 : #include <vcl/dockwin.hxx>
32 : #include <vcl/scrbar.hxx>
33 : #include <tools/svborder.hxx>
34 :
35 : #include <boost/bind.hpp>
36 :
37 : using namespace css;
38 : using namespace css::uno;
39 :
40 :
41 : namespace sfx2 { namespace sidebar {
42 :
43 4702 : Deck::Deck (
44 : const DeckDescriptor& rDeckDescriptor,
45 : vcl::Window* pParentWindow,
46 : const ::boost::function<void(void)>& rCloserAction)
47 : : Window(pParentWindow, 0),
48 : msId(rDeckDescriptor.msId),
49 : maIcon(),
50 : mnMinimalWidth(0),
51 : maPanels(),
52 4702 : mpTitleBar(new DeckTitleBar(rDeckDescriptor.msTitle, this, rCloserAction)),
53 4702 : mpScrollClipWindow(new vcl::Window(this)),
54 9404 : mpScrollContainer(new ScrollContainerWindow(mpScrollClipWindow.get())),
55 4702 : mpFiller(new vcl::Window(this)),
56 28212 : mpVerticalScrollBar(new ScrollBar(this))
57 : {
58 4702 : SetBackground(Wallpaper());
59 :
60 4702 : mpScrollClipWindow->SetBackground(Wallpaper());
61 4702 : mpScrollClipWindow->Show();
62 :
63 4702 : mpScrollContainer->SetStyle(mpScrollContainer->GetStyle() | WB_DIALOGCONTROL);
64 4702 : mpScrollContainer->SetBackground(Wallpaper());
65 4702 : mpScrollContainer->Show();
66 :
67 4702 : mpVerticalScrollBar->SetScrollHdl(LINK(this, Deck, HandleVerticalScrollBarChange));
68 :
69 : #ifdef DEBUG
70 : SetText(OUString("Deck"));
71 : mpScrollClipWindow->SetText(OUString("ScrollClipWindow"));
72 : mpFiller->SetText(OUString("Filler"));
73 : mpVerticalScrollBar->SetText(OUString("VerticalScrollBar"));
74 : #endif
75 4702 : }
76 :
77 :
78 :
79 :
80 14106 : Deck::~Deck (void)
81 : {
82 4702 : Dispose();
83 :
84 : // We have to explicitly trigger the destruction of panels.
85 : // Otherwise that is done by one of our base class destructors
86 : // without updating maPanels.
87 4702 : maPanels.clear();
88 9404 : }
89 :
90 :
91 :
92 :
93 9404 : void Deck::Dispose (void)
94 : {
95 9404 : SharedPanelContainer aPanels;
96 9404 : aPanels.swap(maPanels);
97 14564 : for (SharedPanelContainer::iterator
98 9404 : iPanel(aPanels.begin()),
99 9404 : iEnd(aPanels.end());
100 : iPanel!=iEnd;
101 : ++iPanel)
102 : {
103 5160 : if (*iPanel)
104 : {
105 5160 : (*iPanel)->Dispose();
106 : OSL_ASSERT(iPanel->unique());
107 5160 : iPanel->reset();
108 : }
109 : }
110 :
111 9404 : mpTitleBar.reset();
112 9404 : mpFiller.reset();
113 9404 : mpVerticalScrollBar.reset();
114 9404 : }
115 :
116 :
117 :
118 :
119 :
120 :
121 :
122 :
123 66452 : DeckTitleBar* Deck::GetTitleBar (void) const
124 : {
125 66452 : return mpTitleBar.get();
126 : }
127 :
128 :
129 :
130 :
131 25788 : Rectangle Deck::GetContentArea (void) const
132 : {
133 25788 : const Size aWindowSize (GetSizePixel());
134 25788 : const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
135 :
136 : return Rectangle(
137 25788 : Theme::GetInteger(Theme::Int_DeckLeftPadding) + nBorderSize,
138 25788 : Theme::GetInteger(Theme::Int_DeckTopPadding) + nBorderSize,
139 25788 : aWindowSize.Width() - 1 - Theme::GetInteger(Theme::Int_DeckRightPadding) - nBorderSize,
140 103152 : aWindowSize.Height() - 1 - Theme::GetInteger(Theme::Int_DeckBottomPadding) - nBorderSize);
141 : }
142 :
143 9886 : void Deck::Paint (const Rectangle& rUpdateArea)
144 : {
145 : (void) rUpdateArea;
146 :
147 9886 : const Size aWindowSize (GetSizePixel());
148 : const SvBorder aPadding (
149 9886 : Theme::GetInteger(Theme::Int_DeckLeftPadding),
150 9886 : Theme::GetInteger(Theme::Int_DeckTopPadding),
151 9886 : Theme::GetInteger(Theme::Int_DeckRightPadding),
152 39544 : Theme::GetInteger(Theme::Int_DeckBottomPadding));
153 :
154 : // Paint deck background outside the border.
155 : Rectangle aBox(
156 : 0,
157 : 0,
158 9886 : aWindowSize.Width() - 1,
159 19772 : aWindowSize.Height() - 1);
160 : DrawHelper::DrawBorder(
161 : *this,
162 : aBox,
163 : aPadding,
164 9886 : Theme::GetPaint(Theme::Paint_DeckBackground),
165 19772 : Theme::GetPaint(Theme::Paint_DeckBackground));
166 :
167 : // Paint the border.
168 9886 : const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
169 9886 : aBox.Left() += aPadding.Left();
170 9886 : aBox.Top() += aPadding.Top();
171 9886 : aBox.Right() -= aPadding.Right();
172 9886 : aBox.Bottom() -= aPadding.Bottom();
173 9886 : const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
174 : DrawHelper::DrawBorder(
175 : *this,
176 : aBox,
177 : SvBorder(nBorderSize, nBorderSize, nBorderSize, nBorderSize),
178 : rHorizontalBorderPaint,
179 9886 : Theme::GetPaint(Theme::Paint_VerticalBorder));
180 9886 : }
181 :
182 :
183 :
184 :
185 4 : void Deck::DataChanged (const DataChangedEvent& rEvent)
186 : {
187 : (void)rEvent;
188 4 : RequestLayout();
189 4 : }
190 :
191 107560 : bool Deck::Notify (NotifyEvent& rEvent)
192 : {
193 107560 : if (rEvent.GetType() == EVENT_COMMAND)
194 : {
195 0 : CommandEvent* pCommandEvent = reinterpret_cast<CommandEvent*>(rEvent.GetData());
196 0 : if (pCommandEvent != NULL)
197 0 : switch (pCommandEvent->GetCommand())
198 : {
199 : case COMMAND_WHEEL:
200 0 : return ProcessWheelEvent(pCommandEvent);
201 :
202 : default:
203 0 : break;
204 : }
205 : }
206 :
207 107560 : return Window::Notify(rEvent);
208 : }
209 :
210 0 : bool Deck::ProcessWheelEvent(CommandEvent* pCommandEvent)
211 : {
212 0 : if ( ! mpVerticalScrollBar)
213 0 : return false;
214 0 : if ( ! mpVerticalScrollBar->IsVisible())
215 0 : return false;
216 :
217 : // Get the wheel data and check that it describes a valid vertical
218 : // scroll.
219 0 : const CommandWheelData* pData = pCommandEvent->GetWheelData();
220 0 : if (pData==NULL
221 0 : || pData->GetModifier()
222 0 : || pData->GetMode() != CommandWheelMode::SCROLL
223 0 : || pData->IsHorz())
224 0 : return false;
225 :
226 : // Execute the actual scroll action.
227 0 : long nDelta = pData->GetDelta();
228 : mpVerticalScrollBar->DoScroll(
229 0 : mpVerticalScrollBar->GetThumbPos() - nDelta);
230 0 : return true;
231 : }
232 :
233 5486 : void Deck::SetPanels (const SharedPanelContainer& rPanels)
234 : {
235 5486 : maPanels = rPanels;
236 :
237 5486 : RequestLayout();
238 5486 : }
239 :
240 25788 : void Deck::RequestLayout (void)
241 : {
242 25788 : mnMinimalWidth = 0;
243 :
244 : DeckLayouter::LayoutDeck(
245 : GetContentArea(),
246 : mnMinimalWidth,
247 : maPanels,
248 25788 : *GetTitleBar(),
249 25788 : *mpScrollClipWindow,
250 25788 : *mpScrollContainer,
251 25788 : *mpFiller,
252 77364 : *mpVerticalScrollBar);
253 25788 : }
254 :
255 6950 : vcl::Window* Deck::GetPanelParentWindow (void)
256 : {
257 6950 : return mpScrollContainer.get();
258 : }
259 :
260 0 : void Deck::ShowPanel (const Panel& rPanel)
261 : {
262 0 : if (mpVerticalScrollBar && mpVerticalScrollBar->IsVisible())
263 : {
264 : // Get vertical extent of the panel.
265 0 : sal_Int32 nPanelTop (rPanel.GetPosPixel().Y());
266 0 : const sal_Int32 nPanelBottom (nPanelTop + rPanel.GetSizePixel().Height() - 1);
267 : // Add the title bar into the extent.
268 0 : if (rPanel.GetTitleBar() != NULL && rPanel.GetTitleBar()->IsVisible())
269 0 : nPanelTop = rPanel.GetTitleBar()->GetPosPixel().Y();
270 :
271 : // Determine what the new thumb position should be like.
272 : // When the whole panel does not fit then make its top visible
273 : // and it off at the bottom.
274 0 : sal_Int32 nNewThumbPos (mpVerticalScrollBar->GetThumbPos());
275 0 : if (nPanelBottom >= nNewThumbPos+mpVerticalScrollBar->GetVisibleSize())
276 0 : nNewThumbPos = nPanelBottom - mpVerticalScrollBar->GetVisibleSize();
277 0 : if (nPanelTop < nNewThumbPos)
278 0 : nNewThumbPos = nPanelTop;
279 :
280 0 : mpVerticalScrollBar->SetThumbPos(nNewThumbPos);
281 0 : mpScrollContainer->SetPosPixel(
282 : Point(
283 0 : mpScrollContainer->GetPosPixel().X(),
284 0 : -nNewThumbPos));
285 :
286 : }
287 0 : }
288 :
289 :
290 :
291 :
292 14100 : const OUString GetWindowClassification (const vcl::Window* pWindow)
293 : {
294 14100 : const OUString& rsName (pWindow->GetText());
295 14100 : if (!rsName.isEmpty())
296 : {
297 0 : return rsName;
298 : }
299 : else
300 : {
301 14100 : return OUString("window");
302 14100 : }
303 : }
304 :
305 :
306 14100 : void Deck::PrintWindowSubTree (vcl::Window* pRoot, int nIndentation)
307 : {
308 : static const char* sIndentation = " ";
309 14100 : const Point aLocation (pRoot->GetPosPixel());
310 14100 : const Size aSize (pRoot->GetSizePixel());
311 14100 : OUString sClassification = GetWindowClassification(pRoot);
312 14100 : const char* sVisible = pRoot->IsVisible() ? "visible" : "hidden";
313 : OSL_TRACE("%s%x %s %s +%d+%d x%dx%d",
314 : sIndentation+strlen(sIndentation)-nIndentation*4,
315 : pRoot,
316 : OUStringToOString(sClassification, RTL_TEXTENCODING_ASCII_US).getStr(),
317 : sVisible,
318 : aLocation.X(),aLocation.Y(),
319 : aSize.Width(),aSize.Height());
320 :
321 14100 : const sal_uInt16 nChildCount (pRoot->GetChildCount());
322 23500 : for (sal_uInt16 nIndex=0; nIndex<nChildCount; ++nIndex)
323 23500 : PrintWindowSubTree(pRoot->GetChild(nIndex), nIndentation+1);
324 14100 : }
325 :
326 4700 : void Deck::PrintWindowTree (void)
327 : {
328 4700 : PrintWindowSubTree(this, 0);
329 4700 : }
330 :
331 0 : IMPL_LINK(Deck, HandleVerticalScrollBarChange,void*, EMPTYARG)
332 : {
333 0 : const sal_Int32 nYOffset (-mpVerticalScrollBar->GetThumbPos());
334 0 : mpScrollContainer->SetPosPixel(
335 : Point(
336 0 : mpScrollContainer->GetPosPixel().X(),
337 0 : nYOffset));
338 0 : return sal_True;
339 : }
340 :
341 :
342 :
343 :
344 : //----- Deck::ScrollContainerWindow -------------------------------------------
345 :
346 4702 : Deck::ScrollContainerWindow::ScrollContainerWindow (vcl::Window* pParentWindow)
347 : : Window(pParentWindow),
348 4702 : maSeparators()
349 : {
350 : #ifdef DEBUG
351 : SetText(OUString("ScrollContainerWindow"));
352 : #endif
353 4702 : }
354 :
355 :
356 :
357 :
358 9404 : Deck::ScrollContainerWindow::~ScrollContainerWindow (void)
359 : {
360 9404 : }
361 :
362 :
363 :
364 :
365 7938 : void Deck::ScrollContainerWindow::Paint (const Rectangle& rUpdateArea)
366 : {
367 : (void)rUpdateArea;
368 :
369 : // Paint the separators.
370 7938 : const sal_Int32 nSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
371 7938 : const sal_Int32 nLeft (0);
372 7938 : const sal_Int32 nRight (GetSizePixel().Width()-1);
373 7938 : const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
374 19507 : for (::std::vector<sal_Int32>::const_iterator iY(maSeparators.begin()), iEnd(maSeparators.end());
375 : iY!=iEnd;
376 : ++iY)
377 : {
378 : DrawHelper::DrawHorizontalLine(
379 : *this,
380 : nLeft,
381 : nRight,
382 11569 : *iY,
383 : nSeparatorHeight,
384 11569 : rHorizontalBorderPaint);
385 : }
386 7938 : }
387 :
388 :
389 :
390 :
391 17024 : void Deck::ScrollContainerWindow::SetSeparators (const ::std::vector<sal_Int32>& rSeparators)
392 : {
393 17024 : maSeparators = rSeparators;
394 17024 : }
395 :
396 :
397 951 : } } // end of namespace sfx2::sidebar
398 :
399 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|