1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "taskpane/SubToolPanel.hxx"
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>
31 namespace sd
{ namespace toolpanel
{
34 SubToolPanel::SubToolPanel (
35 Window
& i_rParentWindow
)
36 : Control (&i_rParentWindow
, WB_DIALOGCONTROL
),
39 mbIsRearrangePending(true),
40 mbIsLayoutPending(true),
46 SetAccessibleName (OUString("Sub Task Panel"));
47 mpControlContainer
->SetMultiSelection (true);
49 SetBorderStyle (WINDOW_BORDER_NORMAL
);
50 SetMapMode (MapMode(MAP_PIXEL
));
52 // To reduce flickering during repaints make the container windows
53 // transparent and rely on their children to paint the whole area.
54 SetBackground(Wallpaper());
55 maWindowFiller
.SetBackground(
56 Application::GetSettings().GetStyleSettings().GetWindowColor());
62 SubToolPanel::~SubToolPanel (void)
64 sal_uInt32 nCount
= mpControlContainer
->GetControlCount();
65 for (sal_uInt32 nIndex
=0; nIndex
<nCount
; nIndex
++)
67 TitledControl
* pControl
= static_cast<TitledControl
*>(
68 mpControlContainer
->GetControl(nIndex
));
69 pControl
->GetControl()->GetWindow()->RemoveEventListener(
70 LINK(this,SubToolPanel
,WindowEventListener
));
72 mpControlContainer
->DeleteChildren();
78 void SubToolPanel::Paint (const Rectangle
& rRect
)
80 if (mbIsRearrangePending
)
82 if (mbIsLayoutPending
)
84 ::Window::Paint (rRect
);
86 // Paint the outer border and the space between every two children.
87 Color
aOriginalLineColor (GetLineColor());
88 Color
aOriginalFillColor (GetFillColor());
91 SetFillColor (GetSettings().GetStyleSettings().GetWindowColor());
93 Size
aSize (GetOutputSizePixel());
94 // Paint left and right vertical border.
95 Rectangle
aVerticalArea (
97 Size(mnHorizontalBorder
,aSize
.Height()));
98 DrawRect (aVerticalArea
);
99 aVerticalArea
.Right() += mnHorizontalBorder
+ mnChildrenWidth
- 1;
100 aVerticalArea
.Left() = aVerticalArea
.Right() + mnHorizontalBorder
;
101 DrawRect (aVerticalArea
);
103 // Paint horizontal stripes.
104 Rectangle
aStripeArea (
105 Point (mnHorizontalBorder
,0),
106 Size(mnChildrenWidth
,0));
107 StripeList::const_iterator iStripe
;
108 for (iStripe
=maStripeList
.begin(); iStripe
!=maStripeList
.end(); ++iStripe
)
110 aStripeArea
.Top() = iStripe
->first
;
111 aStripeArea
.Bottom() = iStripe
->second
;
112 if (aStripeArea
.Bottom() < 0)
114 if (aStripeArea
.Top() >= aSize
.Height())
116 DrawRect (aStripeArea
);
119 SetLineColor (aOriginalLineColor
);
120 SetFillColor (aOriginalFillColor
);
126 void SubToolPanel::Resize (void)
129 mbIsRearrangePending
= true;
130 mbIsLayoutPending
= true;
136 void SubToolPanel::RequestResize (void)
138 mbIsRearrangePending
= true;
139 mbIsLayoutPending
= true;
146 Size
SubToolPanel::GetPreferredSize (void)
148 return GetRequiredSize();
154 sal_Int32
SubToolPanel::GetPreferredWidth (sal_Int32
)
156 return GetPreferredSize().Width();
162 sal_Int32
SubToolPanel::GetPreferredHeight (sal_Int32
)
164 return GetPreferredSize().Height();
170 bool SubToolPanel::IsResizable (void)
178 ::Window
* SubToolPanel::GetWindow (void)
186 sal_Int32
SubToolPanel::GetMinimumWidth (void)
188 return TreeNode::GetMinimumWidth();
194 void SubToolPanel::ExpandControl (
196 bool bExpansionState
)
198 // Toggle expand status.
199 pControl
->Expand (bExpansionState
);
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.
213 void SubToolPanel::Rearrange (void)
215 Size
aRequiredSize (GetRequiredSize());
216 if (aRequiredSize
.Width()>0 && aRequiredSize
.Height()>0)
218 Size
aAvailableSize (GetOutputSizePixel());
220 // Make the children at least as wide as the sub tool panel.
221 if (aRequiredSize
.Width() < aAvailableSize
.Width())
222 aRequiredSize
.Width() = aAvailableSize
.Width();
223 mnChildrenWidth
= -2*mnHorizontalBorder
;
224 mnChildrenWidth
+= aAvailableSize
.Width();
228 mbIsRearrangePending
= false;
235 Size
SubToolPanel::GetRequiredSize (void)
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
240 int nChildrenWidth (GetSizePixel().Width());
241 unsigned int nCount
= mpControlContainer
->GetControlCount();
243 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
245 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
246 int nMinimumWidth (pChild
->GetMinimumWidth());
247 if (nMinimumWidth
> nChildrenWidth
)
248 nChildrenWidth
= nMinimumWidth
;
251 // Determine the accumulated width of all children when scaled to the
253 nChildrenWidth
-= 2*mnHorizontalBorder
;
254 Size
aTotalSize (nChildrenWidth
,
255 2*mnVerticalBorder
+ (nCount
-1) * mnVerticalGap
);
256 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
258 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
259 sal_Int32 nHeight
= pChild
->GetPreferredHeight(nChildrenWidth
);
260 aTotalSize
.Height() += nHeight
;
269 sal_Int32
SubToolPanel::LayoutChildren (void)
271 // Determine vertical space that can be distributed to sizable children.
272 unsigned int nCount (mpControlContainer
->GetControlCount());
273 unsigned int nResizableCount
= 0;
274 int nAvailableHeight
= GetSizePixel().Height() - 2*mnVerticalBorder
;
276 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
278 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
279 int nControlHeight
= pChild
->GetPreferredHeight(mnChildrenWidth
);
280 if (pChild
->IsResizable())
283 nAvailableHeight
-= nControlHeight
;
286 maStripeList
.clear();
288 Point
aPosition (0,0);
289 aPosition
.X() += mnHorizontalBorder
;
290 maStripeList
.push_back( ::std::pair
<int,int>(
292 aPosition
.Y() + mnVerticalBorder
- 1));
293 aPosition
.Y() += mnVerticalBorder
;
295 // Place the controls one over the other.
296 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
300 maStripeList
.push_back( ::std::pair
<int,int>(
302 aPosition
.Y() + mnVerticalGap
- 1));
303 aPosition
.Y() += mnVerticalGap
;
305 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
306 int nControlHeight
= pChild
->GetPreferredHeight(mnChildrenWidth
);
307 if (pChild
->IsResizable())
309 nControlHeight
= nAvailableHeight
/ nResizableCount
;
312 nAvailableHeight
-= nControlHeight
;
313 pChild
->GetWindow()->SetPosSizePixel(
315 Size(mnChildrenWidth
, nControlHeight
));
316 aPosition
.Y() += nControlHeight
;
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 int nWindowHeight
= GetSizePixel().Height();
323 if (aPosition
.Y() < nWindowHeight
)
325 maWindowFiller
.SetPosSizePixel (
327 Size(mnChildrenWidth
, nWindowHeight
-aPosition
.Y()));
328 maStripeList
.push_back( ::std::pair
<int,int>(
331 // maScrollWindowFiller.Show();
332 aPosition
.Y() = nWindowHeight
;
335 maWindowFiller
.Hide();
337 aPosition
.Y() += mnVerticalBorder
;
338 mbIsLayoutPending
= false;
340 return aPosition
.Y();
346 IMPL_LINK(SubToolPanel
, WindowEventListener
, VclSimpleEvent
*, pEvent
)
348 if (pEvent
!=NULL
&& pEvent
->ISA(VclWindowEvent
))
350 VclWindowEvent
* pWindowEvent
= static_cast<VclWindowEvent
*>(pEvent
);
351 switch (pWindowEvent
->GetId())
353 case VCLEVENT_WINDOW_SHOW
:
354 case VCLEVENT_WINDOW_HIDE
:
355 case VCLEVENT_WINDOW_ACTIVATE
:
356 case VCLEVENT_WINDOW_RESIZE
:
367 ::com::sun::star::uno::Reference
<
368 ::com::sun::star::accessibility::XAccessible
> SubToolPanel::CreateAccessibleObject (
369 const ::com::sun::star::uno::Reference
<
370 ::com::sun::star::accessibility::XAccessible
>& )
372 return new ::accessibility::AccessibleTreeNode (
376 ::com::sun::star::accessibility::AccessibleRole::PANEL
);
379 } } // end of namespace ::sd::toolpanel
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */