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 :
21 : #include "taskpane/SubToolPanel.hxx"
22 :
23 : #include "TaskPaneFocusManager.hxx"
24 : #include "taskpane/TitleBar.hxx"
25 : #include "taskpane/TitledControl.hxx"
26 : #include "taskpane/ControlContainer.hxx"
27 : #include "AccessibleTreeNode.hxx"
28 : #include <vcl/decoview.hxx>
29 : #include <vcl/svapp.hxx>
30 :
31 : namespace sd { namespace toolpanel {
32 :
33 :
34 0 : SubToolPanel::SubToolPanel (
35 : Window& i_rParentWindow)
36 : : Control (&i_rParentWindow, WB_DIALOGCONTROL),
37 : TreeNode(NULL),
38 : maWindowFiller(this),
39 : mbIsRearrangePending(true),
40 : mbIsLayoutPending(true),
41 : mnChildrenWidth(0),
42 : mnVerticalBorder(0),
43 : mnVerticalGap(3),
44 0 : mnHorizontalBorder(2)
45 : {
46 0 : SetAccessibleName (::rtl::OUString("Sub Task Panel"));
47 0 : mpControlContainer->SetMultiSelection (true);
48 :
49 0 : SetBorderStyle (WINDOW_BORDER_NORMAL);
50 0 : SetMapMode (MapMode(MAP_PIXEL));
51 :
52 : // To reduce flickering during repaints make the container windows
53 : // transparent and rely on their children to paint the whole area.
54 0 : SetBackground(Wallpaper());
55 : maWindowFiller.SetBackground(
56 0 : Application::GetSettings().GetStyleSettings().GetWindowColor());
57 0 : }
58 :
59 :
60 :
61 :
62 0 : SubToolPanel::~SubToolPanel (void)
63 : {
64 0 : sal_uInt32 nCount = mpControlContainer->GetControlCount();
65 0 : for (sal_uInt32 nIndex=0; nIndex<nCount; nIndex++)
66 : {
67 : TitledControl* pControl = static_cast<TitledControl*>(
68 0 : mpControlContainer->GetControl(nIndex));
69 0 : pControl->GetControl()->GetWindow()->RemoveEventListener(
70 0 : LINK(this,SubToolPanel,WindowEventListener));
71 : }
72 0 : mpControlContainer->DeleteChildren();
73 0 : }
74 :
75 :
76 :
77 :
78 0 : void SubToolPanel::Paint (const Rectangle& rRect)
79 : {
80 0 : if (mbIsRearrangePending)
81 0 : Rearrange();
82 0 : if (mbIsLayoutPending)
83 0 : LayoutChildren();
84 0 : ::Window::Paint (rRect);
85 :
86 : // Paint the outer border and the space between every two children.
87 0 : Color aOriginalLineColor (GetLineColor());
88 0 : Color aOriginalFillColor (GetFillColor());
89 :
90 0 : SetLineColor ();
91 0 : SetFillColor (GetSettings().GetStyleSettings().GetWindowColor());
92 :
93 0 : Size aSize (GetOutputSizePixel());
94 : // Paint left and right vertical border.
95 : Rectangle aVerticalArea (
96 : Point(0,0),
97 0 : Size(mnHorizontalBorder,aSize.Height()));
98 0 : DrawRect (aVerticalArea);
99 0 : aVerticalArea.Right() += mnHorizontalBorder + mnChildrenWidth - 1;
100 0 : aVerticalArea.Left() = aVerticalArea.Right() + mnHorizontalBorder;
101 0 : DrawRect (aVerticalArea);
102 :
103 : // Paint horizontal stripes.
104 : Rectangle aStripeArea (
105 : Point (mnHorizontalBorder,0),
106 0 : Size(mnChildrenWidth,0));
107 0 : StripeList::const_iterator iStripe;
108 0 : for (iStripe=maStripeList.begin(); iStripe!=maStripeList.end(); ++iStripe)
109 : {
110 0 : aStripeArea.Top() = iStripe->first;
111 0 : aStripeArea.Bottom() = iStripe->second;
112 0 : if (aStripeArea.Bottom() < 0)
113 0 : continue;
114 0 : if (aStripeArea.Top() >= aSize.Height())
115 0 : break;
116 0 : DrawRect (aStripeArea);
117 : }
118 :
119 0 : SetLineColor (aOriginalLineColor);
120 0 : SetFillColor (aOriginalFillColor);
121 0 : }
122 :
123 :
124 :
125 :
126 0 : void SubToolPanel::Resize (void)
127 : {
128 0 : ::Window::Resize();
129 0 : mbIsRearrangePending = true;
130 0 : mbIsLayoutPending = true;
131 0 : }
132 :
133 :
134 :
135 :
136 0 : void SubToolPanel::RequestResize (void)
137 : {
138 0 : mbIsRearrangePending = true;
139 0 : mbIsLayoutPending = true;
140 0 : Invalidate();
141 0 : }
142 :
143 :
144 :
145 :
146 0 : Size SubToolPanel::GetPreferredSize (void)
147 : {
148 0 : return GetRequiredSize();
149 : }
150 :
151 :
152 :
153 :
154 0 : sal_Int32 SubToolPanel::GetPreferredWidth (sal_Int32 )
155 : {
156 0 : return GetPreferredSize().Width();
157 : }
158 :
159 :
160 :
161 :
162 0 : sal_Int32 SubToolPanel::GetPreferredHeight (sal_Int32 )
163 : {
164 0 : return GetPreferredSize().Height();
165 : }
166 :
167 :
168 :
169 :
170 0 : bool SubToolPanel::IsResizable (void)
171 : {
172 0 : return true;
173 : }
174 :
175 :
176 :
177 :
178 0 : ::Window* SubToolPanel::GetWindow (void)
179 : {
180 0 : return this;
181 : }
182 :
183 :
184 :
185 :
186 0 : sal_Int32 SubToolPanel::GetMinimumWidth (void)
187 : {
188 0 : return TreeNode::GetMinimumWidth();
189 : }
190 :
191 :
192 :
193 :
194 0 : void SubToolPanel::ExpandControl (
195 : TreeNode* pControl,
196 : bool bExpansionState)
197 : {
198 : // Toggle expand status.
199 0 : pControl->Expand (bExpansionState);
200 :
201 0 : Rearrange ();
202 0 : Invalidate ();
203 0 : }
204 :
205 :
206 :
207 :
208 : /** This control shows an expansion bar for every control and in a
209 : separate area below that expansion area it shows all controls each
210 : with its title bar. When there is not enough space then show a
211 : scroll bar in the control area.
212 : */
213 0 : void SubToolPanel::Rearrange (void)
214 : {
215 0 : Size aRequiredSize (GetRequiredSize());
216 0 : if (aRequiredSize.Width()>0 && aRequiredSize.Height()>0)
217 : {
218 0 : Size aAvailableSize (GetOutputSizePixel());
219 :
220 : // Make the children at least as wide as the sub tool panel.
221 0 : if (aRequiredSize.Width() < aAvailableSize.Width())
222 0 : aRequiredSize.Width() = aAvailableSize.Width();
223 0 : mnChildrenWidth = -2*mnHorizontalBorder;
224 0 : mnChildrenWidth += aAvailableSize.Width();
225 :
226 0 : LayoutChildren();
227 :
228 0 : mbIsRearrangePending = false;
229 : }
230 0 : }
231 :
232 :
233 :
234 :
235 0 : Size SubToolPanel::GetRequiredSize (void)
236 : {
237 : // First determine the width of the children. This is the maximum of
238 : // the current window width and the individual minimum widths of the
239 : // children.
240 0 : int nChildrenWidth (GetSizePixel().Width());
241 0 : unsigned int nCount = mpControlContainer->GetControlCount();
242 : unsigned int nIndex;
243 0 : for (nIndex=0; nIndex<nCount; nIndex++)
244 : {
245 0 : TreeNode* pChild = mpControlContainer->GetControl (nIndex);
246 0 : int nMinimumWidth (pChild->GetMinimumWidth());
247 0 : if (nMinimumWidth > nChildrenWidth)
248 0 : nChildrenWidth = nMinimumWidth;
249 : }
250 :
251 : // Determine the accumulated width of all children when scaled to the
252 : // minimum width.
253 0 : nChildrenWidth -= 2*mnHorizontalBorder;
254 : Size aTotalSize (nChildrenWidth,
255 0 : 2*mnVerticalBorder + (nCount-1) * mnVerticalGap);
256 0 : for (nIndex=0; nIndex<nCount; nIndex++)
257 : {
258 0 : TreeNode* pChild = mpControlContainer->GetControl (nIndex);
259 0 : sal_Int32 nHeight = pChild->GetPreferredHeight(nChildrenWidth);
260 0 : aTotalSize.Height() += nHeight;
261 : }
262 :
263 0 : return aTotalSize;
264 : }
265 :
266 :
267 :
268 :
269 0 : sal_Int32 SubToolPanel::LayoutChildren (void)
270 : {
271 : // Determine vertical space that can be distributed to sizable children.
272 0 : unsigned int nCount (mpControlContainer->GetControlCount());
273 0 : unsigned int nResizableCount = 0;
274 0 : int nAvailableHeight = GetSizePixel().Height() - 2*mnVerticalBorder;
275 : unsigned int nIndex;
276 0 : for (nIndex=0; nIndex<nCount; nIndex++)
277 : {
278 0 : TreeNode* pChild = mpControlContainer->GetControl (nIndex);
279 0 : int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth);
280 0 : if (pChild->IsResizable())
281 0 : nResizableCount++;
282 : else
283 0 : nAvailableHeight -= nControlHeight;
284 : }
285 :
286 0 : maStripeList.clear();
287 :
288 0 : Point aPosition (0,0);
289 0 : aPosition.X() += mnHorizontalBorder;
290 : maStripeList.push_back( ::std::pair<int,int>(
291 0 : aPosition.Y(),
292 0 : aPosition.Y() + mnVerticalBorder - 1));
293 0 : aPosition.Y() += mnVerticalBorder;
294 :
295 : // Place the controls one over the other.
296 0 : for (nIndex=0; nIndex<nCount; nIndex++)
297 : {
298 0 : if (nIndex > 0)
299 : {
300 : maStripeList.push_back( ::std::pair<int,int>(
301 0 : aPosition.Y(),
302 0 : aPosition.Y() + mnVerticalGap - 1));
303 0 : aPosition.Y() += mnVerticalGap;
304 : }
305 0 : TreeNode* pChild = mpControlContainer->GetControl (nIndex);
306 0 : int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth);
307 0 : if (pChild->IsResizable())
308 : {
309 0 : nControlHeight = nAvailableHeight / nResizableCount;
310 0 : nResizableCount--;
311 : }
312 0 : nAvailableHeight -= nControlHeight;
313 0 : pChild->GetWindow()->SetPosSizePixel(
314 : aPosition,
315 0 : Size(mnChildrenWidth, nControlHeight));
316 0 : aPosition.Y() += nControlHeight;
317 : }
318 :
319 : // If the children do not cover their parent window completely
320 : // (regarding the height) we put a filler below that is responsible for
321 : // painting the remaining space.
322 0 : int nWindowHeight = GetSizePixel().Height();
323 0 : if (aPosition.Y() < nWindowHeight)
324 : {
325 : maWindowFiller.SetPosSizePixel (
326 : aPosition,
327 0 : Size(mnChildrenWidth, nWindowHeight-aPosition.Y()));
328 : maStripeList.push_back( ::std::pair<int,int>(
329 0 : aPosition.Y(),
330 0 : nWindowHeight-1));
331 : // maScrollWindowFiller.Show();
332 0 : aPosition.Y() = nWindowHeight;
333 : }
334 : else
335 0 : maWindowFiller.Hide();
336 :
337 0 : aPosition.Y() += mnVerticalBorder;
338 0 : mbIsLayoutPending = false;
339 :
340 0 : return aPosition.Y();
341 : }
342 :
343 :
344 :
345 :
346 0 : IMPL_LINK(SubToolPanel, WindowEventListener, VclSimpleEvent*, pEvent)
347 : {
348 0 : if (pEvent!=NULL && pEvent->ISA(VclWindowEvent))
349 : {
350 0 : VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
351 0 : switch (pWindowEvent->GetId())
352 : {
353 : case VCLEVENT_WINDOW_SHOW:
354 : case VCLEVENT_WINDOW_HIDE:
355 : case VCLEVENT_WINDOW_ACTIVATE:
356 : case VCLEVENT_WINDOW_RESIZE:
357 0 : RequestResize();
358 0 : break;
359 : }
360 : }
361 0 : return 0;
362 : }
363 :
364 :
365 :
366 :
367 : ::com::sun::star::uno::Reference<
368 0 : ::com::sun::star::accessibility::XAccessible> SubToolPanel::CreateAccessibleObject (
369 : const ::com::sun::star::uno::Reference<
370 : ::com::sun::star::accessibility::XAccessible>& )
371 : {
372 : return new ::accessibility::AccessibleTreeNode (
373 : *this,
374 : "Sub Task Panel",
375 : "Sub Task Panel",
376 0 : ::com::sun::star::accessibility::AccessibleRole::PANEL);
377 : }
378 :
379 : } } // end of namespace ::sd::toolpanel
380 :
381 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|