Update ooo320-m1
[ooovba.git] / sd / source / ui / toolpanel / SubToolPanel.cxx
blobc345ea643b10773abf05d35cffb54bf56eed23c0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SubToolPanel.cxx,v $
10 * $Revision: 1.11 $
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 (
48 TreeNode* pParent)
49 : Control (pParent->GetWindow(), WB_DIALOGCONTROL),
50 TreeNode(pParent),
51 maWindowFiller(this),
52 mbIsRearrangePending(true),
53 mbIsLayoutPending(true),
54 mnChildrenWidth(0),
55 mnVerticalBorder(0),
56 mnVerticalGap(3),
57 mnHorizontalBorder(2)
59 SetAccessibleName (
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 ();
95 RequestResize ();
101 void SubToolPanel::AddControl (
102 ::std::auto_ptr<TreeNode> pControl,
103 const String& rTitle,
104 ULONG nHelpId)
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(
112 this,
113 pControl,
114 rTitle,
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)
153 Rearrange();
154 if (mbIsLayoutPending)
155 LayoutChildren();
156 ::Window::Paint (rRect);
158 // Paint the outer border and the space between every two children.
159 Color aOriginalLineColor (GetLineColor());
160 Color aOriginalFillColor (GetFillColor());
162 SetLineColor ();
163 SetFillColor (GetSettings().GetStyleSettings().GetWindowColor());
165 Size aSize (GetOutputSizePixel());
166 // Paint left and right vertical border.
167 Rectangle aVerticalArea (
168 Point(0,0),
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)
185 continue;
186 if (aStripeArea.Top() >= aSize.Height())
187 break;
188 DrawRect (aStripeArea);
191 SetLineColor (aOriginalLineColor);
192 SetFillColor (aOriginalFillColor);
198 void SubToolPanel::Resize (void)
200 ::Window::Resize();
201 mbIsRearrangePending = true;
202 mbIsLayoutPending = true;
208 void SubToolPanel::RequestResize (void)
210 mbIsRearrangePending = true;
211 mbIsLayoutPending = true;
212 Invalidate();
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)
244 return true;
250 ::Window* SubToolPanel::GetWindow (void)
252 return this;
258 sal_Int32 SubToolPanel::GetMinimumWidth (void)
260 return TreeNode::GetMinimumWidth();
266 void SubToolPanel::ExpandControl (
267 TreeNode* pControl,
268 bool bExpansionState)
270 // Toggle expand status.
271 pControl->Expand (bExpansionState);
273 Rearrange ();
274 Invalidate ();
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();
298 LayoutChildren();
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
311 // children.
312 int nChildrenWidth (GetSizePixel().Width());
313 unsigned int nCount = mpControlContainer->GetControlCount();
314 unsigned int nIndex;
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
324 // minimum width.
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;
335 return aTotalSize;
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;
347 unsigned int nIndex;
348 for (nIndex=0; nIndex<nCount; nIndex++)
350 TreeNode* pChild = mpControlContainer->GetControl (nIndex);
351 int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth);
352 if (pChild->IsResizable())
353 nResizableCount++;
354 else
355 nAvailableHeight -= nControlHeight;
358 maStripeList.clear();
360 Point aPosition (0,0);
361 aPosition.X() += mnHorizontalBorder;
362 maStripeList.push_back( ::std::pair<int,int>(
363 aPosition.Y(),
364 aPosition.Y() + mnVerticalBorder - 1));
365 aPosition.Y() += mnVerticalBorder;
367 // Place the controls one over the other.
368 for (nIndex=0; nIndex<nCount; nIndex++)
370 if (nIndex > 0)
372 maStripeList.push_back( ::std::pair<int,int>(
373 aPosition.Y(),
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;
382 nResizableCount--;
384 nAvailableHeight -= nControlHeight;
385 pChild->GetWindow()->SetPosSizePixel(
386 aPosition,
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 (
398 aPosition,
399 Size(mnChildrenWidth, nWindowHeight-aPosition.Y()));
400 maStripeList.push_back( ::std::pair<int,int>(
401 aPosition.Y(),
402 nWindowHeight-1));
403 // maScrollWindowFiller.Show();
404 aPosition.Y() = nWindowHeight;
406 else
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:
429 RequestResize();
430 break;
433 return 0;
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 (
445 *this,
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