xref: /aoo42x/main/sfx2/source/sidebar/Deck.cxx (revision 65908a7e)
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, 0),
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->SetBackground(Wallpaper());
72     mpScrollClipWindow->Show();
73 
74     mpScrollContainer->SetStyle(mpScrollContainer->GetStyle() | WB_DIALOGCONTROL);
75     mpScrollContainer->SetBackground(Wallpaper());
76     mpScrollContainer->Show();
77 
78     mpVerticalScrollBar->SetScrollHdl(LINK(this, Deck, HandleVerticalScrollBarChange));
79 
80 #ifdef DEBUG
81     OSL_TRACE("creating Deck at %x", this);
82     SetText(A2S("Deck"));
83     mpScrollClipWindow->SetText(A2S("ScrollClipWindow"));
84     mpFiller->SetText(A2S("Filler"));
85     mpVerticalScrollBar->SetText(A2S("VerticalScrollBar"));
86 #endif
87 }
88 
89 
90 
91 
92 Deck::~Deck (void)
93 {
94     OSL_TRACE("destroying Deck at %x", this);
95     Dispose();
96 
97     // We have to explicitly trigger the destruction of panels.
98     // Otherwise that is done by one of our base class destructors
99     // without updating maPanels.
100     maPanels.clear();
101 }
102 
103 
104 
105 
106 void Deck::Dispose (void)
107 {
108     SharedPanelContainer aPanels;
109     aPanels.swap(maPanels);
110     for (SharedPanelContainer::iterator
111              iPanel(aPanels.begin()),
112              iEnd(aPanels.end());
113          iPanel!=iEnd;
114          ++iPanel)
115     {
116 		if (*iPanel)
117         {
118 			(*iPanel)->Dispose();
119             OSL_ASSERT(iPanel->unique());
120             OSL_TRACE("panel has %d references", iPanel->use_count());
121             iPanel->reset();
122         }
123     }
124 
125     mpTitleBar.reset();
126     mpFiller.reset();
127     mpVerticalScrollBar.reset();
128 }
129 
130 
131 
132 
133 const ::rtl::OUString& Deck::GetId (void) const
134 {
135     return msId;
136 }
137 
138 
139 
140 
141 DeckTitleBar* Deck::GetTitleBar (void) const
142 {
143     return mpTitleBar.get();
144 }
145 
146 
147 
148 
149 Rectangle Deck::GetContentArea (void) const
150 {
151     const Size aWindowSize (GetSizePixel());
152     const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
153 
154     return Rectangle(
155         Theme::GetInteger(Theme::Int_DeckLeftPadding) + nBorderSize,
156         Theme::GetInteger(Theme::Int_DeckTopPadding) + nBorderSize,
157         aWindowSize.Width() - 1 - Theme::GetInteger(Theme::Int_DeckRightPadding) - nBorderSize,
158         aWindowSize.Height() - 1 - Theme::GetInteger(Theme::Int_DeckBottomPadding) - nBorderSize);
159 }
160 
161 
162 
163 
164 ::rtl::OUString Deck::GetIconURL (const bool bIsHighContrastModeActive) const
165 {
166     if (bIsHighContrastModeActive)
167         return msHighContrastIconURL;
168     else
169         return msIconURL;
170 }
171 
172 
173 
174 
175 void Deck::Paint (const Rectangle& rUpdateArea)
176 {
177     (void) rUpdateArea;
178 
179     const Size aWindowSize (GetSizePixel());
180     const SvBorder aPadding (
181             Theme::GetInteger(Theme::Int_DeckLeftPadding),
182             Theme::GetInteger(Theme::Int_DeckTopPadding),
183             Theme::GetInteger(Theme::Int_DeckRightPadding),
184             Theme::GetInteger(Theme::Int_DeckBottomPadding));
185 
186     // Paint deck background outside the border.
187     Rectangle aBox(
188         0,
189         0,
190         aWindowSize.Width() - 1,
191         aWindowSize.Height() - 1);
192     DrawHelper::DrawBorder(
193         *this,
194         aBox,
195         aPadding,
196         Theme::GetPaint(Theme::Paint_DeckBackground),
197         Theme::GetPaint(Theme::Paint_DeckBackground));
198 
199     // Paint the border.
200     const int nBorderSize (Theme::GetInteger(Theme::Int_DeckBorderSize));
201     aBox.Left() += aPadding.Left();
202     aBox.Top() += aPadding.Top();
203     aBox.Right() -= aPadding.Right();
204     aBox.Bottom() -= aPadding.Bottom();
205     const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
206     DrawHelper::DrawBorder(
207         *this,
208         aBox,
209         SvBorder(nBorderSize, nBorderSize, nBorderSize, nBorderSize),
210         rHorizontalBorderPaint,
211         Theme::GetPaint(Theme::Paint_VerticalBorder));
212 }
213 
214 
215 
216 
217 void Deck::DataChanged (const DataChangedEvent& rEvent)
218 {
219     (void)rEvent;
220     RequestLayout();
221 }
222 
223 
224 
225 
226 void Deck::SetPanels (const SharedPanelContainer& rPanels)
227 {
228     maPanels = rPanels;
229 
230     RequestLayout();
231 }
232 
233 
234 
235 
236 const SharedPanelContainer& Deck::GetPanels (void) const
237 {
238     return maPanels;
239 }
240 
241 
242 
243 
244 void Deck::RequestLayout (void)
245 {
246     PrintWindowTree();
247 
248     DeckLayouter::LayoutDeck(
249         GetContentArea(),
250         maPanels,
251         *GetTitleBar(),
252         *mpScrollClipWindow,
253         *mpScrollContainer,
254         *mpFiller,
255         *mpVerticalScrollBar);
256 
257     Invalidate();
258 }
259 
260 
261 
262 
263 ::Window* Deck::GetPanelParentWindow (void)
264 {
265     return mpScrollContainer.get();
266 }
267 
268 
269 
270 
271 const char* GetWindowClassification (const Window* pWindow)
272 {
273     const String& rsName (pWindow->GetText());
274     if (rsName.Len() > 0)
275     {
276         return ::rtl::OUStringToOString(rsName, RTL_TEXTENCODING_ASCII_US).getStr();
277     }
278     else
279     {
280         static char msWindow[] = "window";
281         return msWindow;
282     }
283 }
284 
285 
286 void Deck::PrintWindowSubTree (Window* pRoot, int nIndentation)
287 {
288     static char* sIndentation = "                                                                  ";
289     const Point aLocation (pRoot->GetPosPixel());
290     const Size aSize (pRoot->GetSizePixel());
291     const char* sClassification = GetWindowClassification(pRoot);
292     const char* sVisible = pRoot->IsVisible() ? "visible" : "hidden";
293     OSL_TRACE("%s%x %s %s +%d+%d x%dx%d",
294         sIndentation+strlen(sIndentation)-nIndentation*4,
295         pRoot,
296         sClassification,
297         sVisible,
298         aLocation.X(),aLocation.Y(),
299         aSize.Width(),aSize.Height());
300 
301     const sal_uInt16 nChildCount (pRoot->GetChildCount());
302     for (sal_uInt16 nIndex=0; nIndex<nChildCount; ++nIndex)
303         PrintWindowSubTree(pRoot->GetChild(nIndex), nIndentation+1);
304 }
305 
306 
307 
308 
309 void Deck::PrintWindowTree (void)
310 {
311     PrintWindowSubTree(this, 0);
312 }
313 
314 
315 
316 
317 void Deck::PrintWindowTree (const ::std::vector<Panel*>& rPanels)
318 {
319     (void)rPanels;
320 
321     PrintWindowTree();
322 }
323 
324 
325 
326 
327 IMPL_LINK(Deck, HandleVerticalScrollBarChange,void*, EMPTYARG)
328 {
329     const sal_Int32 nYOffset (-mpVerticalScrollBar->GetThumbPos());
330     mpScrollContainer->SetPosPixel(
331         Point(
332             mpScrollContainer->GetPosPixel().X(),
333             nYOffset));
334     return sal_True;
335 }
336 
337 
338 
339 
340 //----- Deck::ScrollContainerWindow -------------------------------------------
341 
342 Deck::ScrollContainerWindow::ScrollContainerWindow (Window* pParentWindow)
343     : Window(pParentWindow),
344       maSeparators()
345 {
346 #ifdef DEBUG
347     SetText(A2S("ScrollContainerWindow"));
348 #endif
349 }
350 
351 
352 
353 
354 Deck::ScrollContainerWindow::~ScrollContainerWindow (void)
355 {
356 }
357 
358 
359 
360 
361 void Deck::ScrollContainerWindow::Paint (const Rectangle& rUpdateArea)
362 {
363     (void)rUpdateArea;
364 
365     // Paint the separators.
366     const sal_Int32 nSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
367     const sal_Int32 nLeft  (0);
368     const sal_Int32 nRight (GetSizePixel().Width()-1);
369     const sfx2::sidebar::Paint& rHorizontalBorderPaint (Theme::GetPaint(Theme::Paint_HorizontalBorder));
370     for (::std::vector<sal_Int32>::const_iterator iY(maSeparators.begin()), iEnd(maSeparators.end());
371          iY!=iEnd;
372          ++iY)
373     {
374         DrawHelper::DrawHorizontalLine(
375             *this,
376             nLeft,
377             nRight,
378             *iY,
379             nSeparatorHeight,
380             rHorizontalBorderPaint);
381     }
382 }
383 
384 
385 
386 
387 void Deck::ScrollContainerWindow::SetSeparators (const ::std::vector<sal_Int32>& rSeparators)
388 {
389     maSeparators = rSeparators;
390 }
391 
392 } } // end of namespace sfx2::sidebar
393