1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SubToolPanel.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "taskpane/SubToolPanel.hxx"
36 #include "TaskPaneFocusManager.hxx"
37 #include "taskpane/TitleBar.hxx"
38 #include "taskpane/TitledControl.hxx"
39 #include "taskpane/ControlContainer.hxx"
40 #include "AccessibleTreeNode.hxx"
41 #include <vcl/decoview.hxx>
42 #include <vcl/svapp.hxx>
44 namespace sd
{ namespace toolpanel
{
47 SubToolPanel::SubToolPanel (
49 : Control (pParent
->GetWindow(), WB_DIALOGCONTROL
),
52 mbIsRearrangePending(true),
53 mbIsLayoutPending(true),
60 ::rtl::OUString::createFromAscii("Sub Task Panel"));
61 mpControlContainer
->SetMultiSelection (true);
63 SetBorderStyle (WINDOW_BORDER_NORMAL
);
64 SetMapMode (MapMode(MAP_PIXEL
));
66 // To reduce flickering during repaints make the container windows
67 // transparent and rely on their children to paint the whole area.
68 SetBackground(Wallpaper());
69 maWindowFiller
.SetBackground(
70 Application::GetSettings().GetStyleSettings().GetWindowColor());
76 SubToolPanel::~SubToolPanel (void)
78 sal_uInt32 nCount
= mpControlContainer
->GetControlCount();
79 for (sal_uInt32 nIndex
=0; nIndex
<nCount
; nIndex
++)
81 TitledControl
* pControl
= static_cast<TitledControl
*>(
82 mpControlContainer
->GetControl(nIndex
));
83 pControl
->GetControl()->GetWindow()->RemoveEventListener(
84 LINK(this,SubToolPanel
,WindowEventListener
));
86 mpControlContainer
->DeleteChildren();
92 void SubToolPanel::ListHasChanged (void)
94 mpControlContainer
->ListHasChanged ();
101 void SubToolPanel::AddControl (
102 ::std::auto_ptr
<TreeNode
> pControl
,
103 const String
& rTitle
,
106 pControl
->GetWindow()->AddEventListener (
107 LINK(this,SubToolPanel
,WindowEventListener
));
109 // We are interested only in the title. The control itself is
110 // managed by the content object.
111 TitledControl
* pTitledControl
= new TitledControl(
115 TitledControlStandardClickHandler(GetControlContainer(), ControlContainer::ES_TOGGLE
),
116 TitleBar::TBT_SUB_CONTROL_HEADLINE
);
117 pTitledControl
->GetWindow()->SetParent(this);
118 pTitledControl
->GetWindow()->SetHelpId(nHelpId
);
119 ::std::auto_ptr
<TreeNode
> pChild (pTitledControl
);
121 // Add a down link only for the first control so that when
122 // entering the sub tool panel the focus is set to the first control.
123 if (mpControlContainer
->GetControlCount() == 0)
124 FocusManager::Instance().RegisterDownLink(GetParent(), pTitledControl
->GetWindow());
125 FocusManager::Instance().RegisterUpLink(pTitledControl
->GetWindow(), GetParent());
127 mpControlContainer
->AddControl (pChild
);
133 void SubToolPanel::AddControl (::std::auto_ptr
<TreeNode
> pControl
)
135 pControl
->GetWindow()->AddEventListener (
136 LINK(this,SubToolPanel
,WindowEventListener
));
138 // Add a down link only for the first control so that when
139 // entering the sub tool panel the focus is set to the first control.
140 if (mpControlContainer
->GetControlCount() == 0)
141 FocusManager::Instance().RegisterDownLink(GetParent(), pControl
->GetWindow());
142 FocusManager::Instance().RegisterUpLink(pControl
->GetWindow(), GetParent());
144 mpControlContainer
->AddControl (pControl
);
150 void SubToolPanel::Paint (const Rectangle
& rRect
)
152 if (mbIsRearrangePending
)
154 if (mbIsLayoutPending
)
156 ::Window::Paint (rRect
);
158 // Paint the outer border and the space between every two children.
159 Color
aOriginalLineColor (GetLineColor());
160 Color
aOriginalFillColor (GetFillColor());
163 SetFillColor (GetSettings().GetStyleSettings().GetWindowColor());
165 Size
aSize (GetOutputSizePixel());
166 // Paint left and right vertical border.
167 Rectangle
aVerticalArea (
169 Size(mnHorizontalBorder
,aSize
.Height()));
170 DrawRect (aVerticalArea
);
171 aVerticalArea
.Right() += mnHorizontalBorder
+ mnChildrenWidth
- 1;
172 aVerticalArea
.Left() = aVerticalArea
.Right() + mnHorizontalBorder
;
173 DrawRect (aVerticalArea
);
175 // Paint horizontal stripes.
176 Rectangle
aStripeArea (
177 Point (mnHorizontalBorder
,0),
178 Size(mnChildrenWidth
,0));
179 StripeList::const_iterator iStripe
;
180 for (iStripe
=maStripeList
.begin(); iStripe
!=maStripeList
.end(); iStripe
++)
182 aStripeArea
.Top() = iStripe
->first
;
183 aStripeArea
.Bottom() = iStripe
->second
;
184 if (aStripeArea
.Bottom() < 0)
186 if (aStripeArea
.Top() >= aSize
.Height())
188 DrawRect (aStripeArea
);
191 SetLineColor (aOriginalLineColor
);
192 SetFillColor (aOriginalFillColor
);
198 void SubToolPanel::Resize (void)
201 mbIsRearrangePending
= true;
202 mbIsLayoutPending
= true;
208 void SubToolPanel::RequestResize (void)
210 mbIsRearrangePending
= true;
211 mbIsLayoutPending
= true;
218 Size
SubToolPanel::GetPreferredSize (void)
220 return GetRequiredSize();
226 sal_Int32
SubToolPanel::GetPreferredWidth (sal_Int32
)
228 return GetPreferredSize().Width();
234 sal_Int32
SubToolPanel::GetPreferredHeight (sal_Int32
)
236 return GetPreferredSize().Height();
242 bool SubToolPanel::IsResizable (void)
250 ::Window
* SubToolPanel::GetWindow (void)
258 sal_Int32
SubToolPanel::GetMinimumWidth (void)
260 return TreeNode::GetMinimumWidth();
266 void SubToolPanel::ExpandControl (
268 bool bExpansionState
)
270 // Toggle expand status.
271 pControl
->Expand (bExpansionState
);
280 /** This control shows an expansion bar for every control and in a
281 separate area below that expansion area it shows all controls each
282 with its title bar. When there is not enough space then show a
283 scroll bar in the control area.
285 void SubToolPanel::Rearrange (void)
287 Size
aRequiredSize (GetRequiredSize());
288 if (aRequiredSize
.Width()>0 && aRequiredSize
.Height()>0)
290 Size
aAvailableSize (GetOutputSizePixel());
292 // Make the children at least as wide as the sub tool panel.
293 if (aRequiredSize
.Width() < aAvailableSize
.Width())
294 aRequiredSize
.Width() = aAvailableSize
.Width();
295 mnChildrenWidth
= -2*mnHorizontalBorder
;
296 mnChildrenWidth
+= aAvailableSize
.Width();
300 mbIsRearrangePending
= false;
307 Size
SubToolPanel::GetRequiredSize (void)
309 // First determine the width of the children. This is the maximum of
310 // the current window width and the individual minimum widths of the
312 int nChildrenWidth (GetSizePixel().Width());
313 unsigned int nCount
= mpControlContainer
->GetControlCount();
315 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
317 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
318 int nMinimumWidth (pChild
->GetMinimumWidth());
319 if (nMinimumWidth
> nChildrenWidth
)
320 nChildrenWidth
= nMinimumWidth
;
323 // Determine the accumulated width of all children when scaled to the
325 nChildrenWidth
-= 2*mnHorizontalBorder
;
326 Size
aTotalSize (nChildrenWidth
,
327 2*mnVerticalBorder
+ (nCount
-1) * mnVerticalGap
);
328 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
330 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
331 sal_Int32 nHeight
= pChild
->GetPreferredHeight(nChildrenWidth
);
332 aTotalSize
.Height() += nHeight
;
341 sal_Int32
SubToolPanel::LayoutChildren (void)
343 // Determine vertical space that can be distributed to sizable children.
344 unsigned int nCount (mpControlContainer
->GetControlCount());
345 unsigned int nResizableCount
= 0;
346 int nAvailableHeight
= GetSizePixel().Height() - 2*mnVerticalBorder
;
348 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
350 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
351 int nControlHeight
= pChild
->GetPreferredHeight(mnChildrenWidth
);
352 if (pChild
->IsResizable())
355 nAvailableHeight
-= nControlHeight
;
358 maStripeList
.clear();
360 Point
aPosition (0,0);
361 aPosition
.X() += mnHorizontalBorder
;
362 maStripeList
.push_back( ::std::pair
<int,int>(
364 aPosition
.Y() + mnVerticalBorder
- 1));
365 aPosition
.Y() += mnVerticalBorder
;
367 // Place the controls one over the other.
368 for (nIndex
=0; nIndex
<nCount
; nIndex
++)
372 maStripeList
.push_back( ::std::pair
<int,int>(
374 aPosition
.Y() + mnVerticalGap
- 1));
375 aPosition
.Y() += mnVerticalGap
;
377 TreeNode
* pChild
= mpControlContainer
->GetControl (nIndex
);
378 int nControlHeight
= pChild
->GetPreferredHeight(mnChildrenWidth
);
379 if (pChild
->IsResizable())
381 nControlHeight
= nAvailableHeight
/ nResizableCount
;
384 nAvailableHeight
-= nControlHeight
;
385 pChild
->GetWindow()->SetPosSizePixel(
387 Size(mnChildrenWidth
, nControlHeight
));
388 aPosition
.Y() += nControlHeight
;
391 // If the children do not cover their parent window completely
392 // (regarding the height) we put a filler below that is responsible for
393 // painting the remaining space.
394 int nWindowHeight
= GetSizePixel().Height();
395 if (aPosition
.Y() < nWindowHeight
)
397 maWindowFiller
.SetPosSizePixel (
399 Size(mnChildrenWidth
, nWindowHeight
-aPosition
.Y()));
400 maStripeList
.push_back( ::std::pair
<int,int>(
403 // maScrollWindowFiller.Show();
404 aPosition
.Y() = nWindowHeight
;
407 maWindowFiller
.Hide();
409 aPosition
.Y() += mnVerticalBorder
;
410 mbIsLayoutPending
= false;
412 return aPosition
.Y();
418 IMPL_LINK(SubToolPanel
, WindowEventListener
, VclSimpleEvent
*, pEvent
)
420 if (pEvent
!=NULL
&& pEvent
->ISA(VclWindowEvent
))
422 VclWindowEvent
* pWindowEvent
= static_cast<VclWindowEvent
*>(pEvent
);
423 switch (pWindowEvent
->GetId())
425 case VCLEVENT_WINDOW_SHOW
:
426 case VCLEVENT_WINDOW_HIDE
:
427 case VCLEVENT_WINDOW_ACTIVATE
:
428 case VCLEVENT_WINDOW_RESIZE
:
439 ::com::sun::star::uno::Reference
<
440 ::com::sun::star::accessibility::XAccessible
> SubToolPanel::CreateAccessibleObject (
441 const ::com::sun::star::uno::Reference
<
442 ::com::sun::star::accessibility::XAccessible
>& )
444 return new ::accessibility::AccessibleTreeNode (
446 ::rtl::OUString::createFromAscii("Sub Task Panel"),
447 ::rtl::OUString::createFromAscii("Sub Task Panel"),
448 ::com::sun::star::accessibility::AccessibleRole::PANEL
);
451 } } // end of namespace ::sd::toolpanel