xref: /trunk/main/sfx2/source/sidebar/Deck.cxx (revision f120fe41)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "precompiled_sfx2.hxx"
23 
24 #include "Deck.hxx"
25 #include "DeckDescriptor.hxx"
26 #include "DeckLayouter.hxx"
27 #include "DrawHelper.hxx"
28 #include "DeckTitleBar.hxx"
29 #include "Paint.hxx"
30 #include "Panel.hxx"
31 #include "ToolBoxBackground.hxx"
32 #include "Tools.hxx"
33 #include "sfx2/sidebar/Theme.hxx"
34 
35 #include <vcl/dockwin.hxx>
36 #include <vcl/scrbar.hxx>
37 #include <tools/svborder.hxx>
38 
39 #include <boost/bind.hpp>
40 
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
43 
44 
45 namespace sfx2 { namespace sidebar {
46 
47 
48 namespace {
49     static const sal_Int32 MinimalPanelHeight (25);
50 }
51 
52 
53 Deck::Deck (
54     const DeckDescriptor& rDeckDescriptor,
55     Window* pParentWindow,
56     const ::boost::function<void(void)>& rCloserAction)
57     : Window(pParentWindow),
58       msId(rDeckDescriptor.msId),
59       maIcon(),
60       msIconURL(rDeckDescriptor.msIconURL),
61       msHighContrastIconURL(rDeckDescriptor.msHighContrastIconURL),
62       maPanels(),
63       mpTitleBar(new DeckTitleBar(rDeckDescriptor.msTitle, this, rCloserAction)),
64       mpScrollClipWindow(new Window(this)),
65       mpScrollContainer(new ScrollContainerWindow(mpScrollClipWindow.get())),
66       mpFiller(new Window(this)),
67       mpVerticalScrollBar(new ScrollBar(this))
68 {
69     SetBackground(Wallpaper());
70 
71     mpScrollClipWindow->Show();
72     mpScrollClipWindow->SetBackground(Wallpaper());
73     mpScrollContainer->Show();
74     mpScrollContainer->SetBackground(Wallpaper());
75 
76     mpVerticalScrollBar->SetScrollHdl(LINK(this, Deck, HandleVerticalScrollBarChange));
77 
78 #ifdef DEBUG
79     OSL_TRACE("creating Deck at %x", this);
80     SetText(A2S("Deck"));
81     mpScrollClipWindow->SetText(A2S("ScrollClipWindow"));
82     mpFiller->SetText(A2S("Filler"));
83     mpVerticalScrollBar->SetText(A2S("VerticalScrollBar"));
84 #endif
85 }
86 
87 
88 
89 
90 Deck::~Deck (void)
91 {
92     OSL_TRACE("destroying Deck at %x", this);
93     Dispose();
94 
95     // We have to explicitly trigger the destruction of panels.
96     // Otherwise that is done by one of our base class destructors
97     // without updating maPanels.
98     maPanels.clear();
99 }
100 
101 
102 
103 
104 void Deck::Dispose (void)
105 {
106     SharedPanelContainer aPanels;
107     aPanels.swap(maPanels);
108     for (SharedPanelContainer::iterator
109              iPanel(aPanels.begin()),
110              iEnd(aPanels.end());
111          iPanel!=iEnd;
112          ++iPanel)
113     {
114 		if (*iPanel)
115         {
116 			(*iPanel)->Dispose();
117             OSL_ASSERT(iPanel->unique());
118             OSL_TRACE("panel has %d references", iPanel->use_count());
119             iPanel->reset();
120         }
121     }
122 
123     mpTitleBar.reset();
124     mpFiller.reset();
125     mpVerticalScrollBar.reset();
126 }
127 
128 
129 
130 
131 const ::rtl::OUString& Deck::GetId (void) const
132 {
133     return msId;
134 }
135 
136 
137 
138 
139 DeckTitleBar* Deck::GetTitleBar (void) const
140 {
141     return mpTitleBar.get();
142 }
143 
144 
145 
146 
147 Rectangle Deck::GetContentArea (void) const
148 {
149     const Size aWindowSize (GetSizePixel());
150     const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
151 
152     return Rectangle(
153         Theme::GetInteger(Theme::Int_DeckLeftPadding) + nBorderSize,
154         Theme::GetInteger(Theme::Int_DeckTopPadding) + nBorderSize,
155         aWindowSize.Width() - 1 - Theme::GetInteger(Theme::Int_DeckRightPadding) - nBorderSize,
156         aWindowSize.Height() - 1 - Theme::GetInteger(Theme::Int_DeckBottomPadding) - nBorderSize);
157 }
158 
159 
160 
161 
162 ::rtl::OUString Deck::GetIconURL (const bool bIsHighContrastModeActive) const
163 {
164     if (bIsHighContrastModeActive)
165         return msHighContrastIconURL;
166     else
167         return msIconURL;
168 }
169 
170 
171 
172 
173 void Deck::Paint (const Rectangle& rUpdateArea)
174 {
175     (void) rUpdateArea;
176 
177     const Size aWindowSize (GetSizePixel());
178     const SvBorder aPadding (
179             Theme::GetInteger(Theme::Int_DeckLeftPadding),
180             Theme::GetInteger(Theme::Int_DeckTopPadding),
181             Theme::GetInteger(Theme::Int_DeckRightPadding),
182             Theme::GetInteger(Theme::Int_DeckBottomPadding));
183 
184     // Paint deck background outside the border.
185     Rectangle aBox(
186         0,
187         0,
188         aWindowSize.Width() - 1,
189         aWindowSize.Height() - 1);
190     DrawHelper::DrawBorder(
191         *this,
192         aBox,
193         aPadding,
194         Theme::GetPaint(Theme::Paint_DeckBackground),
195         Theme::GetPaint(Theme::Paint_DeckBackground));
196 
197     // Paint the border.
198     const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
199     aBox.Left() += aPadding.Left();
200     aBox.Top() += aPadding.Top();
201     aBox.Right() -= aPadding.Right();
202     aBox.Bottom() -= aPadding.Bottom();
203     const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
204     DrawHelper::DrawBorder(
205         *this,
206         aBox,
207         SvBorder(nBorderSize, nBorderSize, nBorderSize, nBorderSize),
208         rHorizontalBorderPaint,
209         Theme::GetPaint(Theme::Paint_VerticalBorder));
210 }
211 
212 
213 
214 
215 void Deck::DataChanged (const DataChangedEvent& rEvent)
216 {
217     (void)rEvent;
218     RequestLayout();
219 }
220 
221 
222 
223 
224 void Deck::SetPanels (const SharedPanelContainer& rPanels)
225 {
226     maPanels = rPanels;
227 
228     RequestLayout();
229 }
230 
231 
232 
233 
234 const SharedPanelContainer& Deck::GetPanels (void) const
235 {
236     return maPanels;
237 }
238 
239 
240 
241 
242 void Deck::RequestLayout (void)
243 {
244     PrintWindowTree();
245 
246     DeckLayouter::LayoutDeck(
247         GetContentArea(),
248         maPanels,
249         *GetTitleBar(),
250         *mpScrollClipWindow,
251         *mpScrollContainer,
252         *mpFiller,
253         *mpVerticalScrollBar);
254 
255     Invalidate();
256 }
257 
258 
259 
260 
261 ::Window* Deck::GetPanelParentWindow (void)
262 {
263     return mpScrollContainer.get();
264 }
265 
266 
267 
268 
269 const char* GetWindowClassification (const Window* pWindow)
270 {
271     const String& rsName (pWindow->GetText());
272     if (rsName.Len() > 0)
273     {
274         return ::rtl::OUStringToOString(rsName, RTL_TEXTENCODING_ASCII_US).getStr();
275     }
276     else
277     {
278         static char msWindow[] = "window";
279         return msWindow;
280     }
281 }
282 
283 
284 void Deck::PrintWindowSubTree (Window* pRoot, int nIndentation)
285 {
286     static char* sIndentation = "                                                                  ";
287     const Point aLocation (pRoot->GetPosPixel());
288     const Size aSize (pRoot->GetSizePixel());
289     const char* sClassification = GetWindowClassification(pRoot);
290     const char* sVisible = pRoot->IsVisible() ? "visible" : "hidden";
291     OSL_TRACE("%s%x %s %s +%d+%d x%dx%d",
292         sIndentation+strlen(sIndentation)-nIndentation*4,
293         pRoot,
294         sClassification,
295         sVisible,
296         aLocation.X(),aLocation.Y(),
297         aSize.Width(),aSize.Height());
298 
299     const sal_uInt16 nChildCount (pRoot->GetChildCount());
300     for (sal_uInt16 nIndex=0; nIndex<nChildCount; ++nIndex)
301         PrintWindowSubTree(pRoot->GetChild(nIndex), nIndentation+1);
302 }
303 
304 
305 
306 
307 void Deck::PrintWindowTree (void)
308 {
309     PrintWindowSubTree(this, 0);
310 }
311 
312 
313 
314 
315 void Deck::PrintWindowTree (const ::std::vector<Panel*>& rPanels)
316 {
317     (void)rPanels;
318 
319     PrintWindowTree();
320 }
321 
322 
323 
324 
325 IMPL_LINK(Deck, HandleVerticalScrollBarChange,void*, EMPTYARG)
326 {
327     const sal_Int32 nYOffset (-mpVerticalScrollBar->GetThumbPos());
328     mpScrollContainer->SetPosPixel(
329         Point(
330             mpScrollContainer->GetPosPixel().X(),
331             nYOffset));
332     return sal_True;
333 }
334 
335 
336 
337 
338 //----- Deck::ScrollContainerWindow -------------------------------------------
339 
340 Deck::ScrollContainerWindow::ScrollContainerWindow (Window* pParentWindow)
341     : Window(pParentWindow),
342       maSeparators()
343 {
344 #ifdef DEBUG
345     SetText(A2S("ScrollContainerWindow"));
346 #endif
347 }
348 
349 
350 
351 
352 Deck::ScrollContainerWindow::~ScrollContainerWindow (void)
353 {
354 }
355 
356 
357 
358 
359 void Deck::ScrollContainerWindow::Paint (const Rectangle& rUpdateArea)
360 {
361     (void)rUpdateArea;
362 
363     // Paint the separators.
364     const sal_Int32 nSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
365     const sal_Int32 nLeft  (0);
366     const sal_Int32 nRight (GetSizePixel().Width()-1);
367     const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
368     for (::std::vector<sal_Int32>::const_iterator iY(maSeparators.begin()), iEnd(maSeparators.end());
369          iY!=iEnd;
370          ++iY)
371     {
372         DrawHelper::DrawHorizontalLine(
373             *this,
374             nLeft,
375             nRight,
376             *iY,
377             nSeparatorHeight,
378             rHorizontalBorderPaint);
379     }
380 }
381 
382 
383 
384 
385 void Deck::ScrollContainerWindow::SetSeparators (const ::std::vector<sal_Int32>& rSeparators)
386 {
387     maSeparators = rSeparators;
388 }
389 
390 } } // end of namespace sfx2::sidebar
391