/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: SubToolPanel.cxx,v $ * $Revision: 1.11 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" #include "taskpane/SubToolPanel.hxx" #include "TaskPaneFocusManager.hxx" #include "taskpane/TitleBar.hxx" #include "taskpane/TitledControl.hxx" #include "taskpane/ControlContainer.hxx" #include "AccessibleTreeNode.hxx" #include #include namespace sd { namespace toolpanel { SubToolPanel::SubToolPanel ( TreeNode* pParent) : Control (pParent->GetWindow(), WB_DIALOGCONTROL), TreeNode(pParent), maWindowFiller(this), mbIsRearrangePending(true), mbIsLayoutPending(true), mnChildrenWidth(0), mnVerticalBorder(0), mnVerticalGap(3), mnHorizontalBorder(2) { SetAccessibleName ( ::rtl::OUString::createFromAscii("Sub Task Panel")); mpControlContainer->SetMultiSelection (true); SetBorderStyle (WINDOW_BORDER_NORMAL); SetMapMode (MapMode(MAP_PIXEL)); // To reduce flickering during repaints make the container windows // transparent and rely on their children to paint the whole area. SetBackground(Wallpaper()); maWindowFiller.SetBackground( Application::GetSettings().GetStyleSettings().GetWindowColor()); } SubToolPanel::~SubToolPanel (void) { sal_uInt32 nCount = mpControlContainer->GetControlCount(); for (sal_uInt32 nIndex=0; nIndex( mpControlContainer->GetControl(nIndex)); pControl->GetControl()->GetWindow()->RemoveEventListener( LINK(this,SubToolPanel,WindowEventListener)); } mpControlContainer->DeleteChildren(); } void SubToolPanel::ListHasChanged (void) { mpControlContainer->ListHasChanged (); RequestResize (); } void SubToolPanel::AddControl ( ::std::auto_ptr pControl, const String& rTitle, ULONG nHelpId) { pControl->GetWindow()->AddEventListener ( LINK(this,SubToolPanel,WindowEventListener)); // We are interested only in the title. The control itself is // managed by the content object. TitledControl* pTitledControl = new TitledControl( this, pControl, rTitle, TitledControlStandardClickHandler(GetControlContainer(), ControlContainer::ES_TOGGLE), TitleBar::TBT_SUB_CONTROL_HEADLINE); pTitledControl->GetWindow()->SetParent(this); pTitledControl->GetWindow()->SetHelpId(nHelpId); ::std::auto_ptr pChild (pTitledControl); // Add a down link only for the first control so that when // entering the sub tool panel the focus is set to the first control. if (mpControlContainer->GetControlCount() == 0) FocusManager::Instance().RegisterDownLink(GetParent(), pTitledControl->GetWindow()); FocusManager::Instance().RegisterUpLink(pTitledControl->GetWindow(), GetParent()); mpControlContainer->AddControl (pChild); } void SubToolPanel::AddControl (::std::auto_ptr pControl) { pControl->GetWindow()->AddEventListener ( LINK(this,SubToolPanel,WindowEventListener)); // Add a down link only for the first control so that when // entering the sub tool panel the focus is set to the first control. if (mpControlContainer->GetControlCount() == 0) FocusManager::Instance().RegisterDownLink(GetParent(), pControl->GetWindow()); FocusManager::Instance().RegisterUpLink(pControl->GetWindow(), GetParent()); mpControlContainer->AddControl (pControl); } void SubToolPanel::Paint (const Rectangle& rRect) { if (mbIsRearrangePending) Rearrange(); if (mbIsLayoutPending) LayoutChildren(); ::Window::Paint (rRect); // Paint the outer border and the space between every two children. Color aOriginalLineColor (GetLineColor()); Color aOriginalFillColor (GetFillColor()); SetLineColor (); SetFillColor (GetSettings().GetStyleSettings().GetWindowColor()); Size aSize (GetOutputSizePixel()); // Paint left and right vertical border. Rectangle aVerticalArea ( Point(0,0), Size(mnHorizontalBorder,aSize.Height())); DrawRect (aVerticalArea); aVerticalArea.Right() += mnHorizontalBorder + mnChildrenWidth - 1; aVerticalArea.Left() = aVerticalArea.Right() + mnHorizontalBorder; DrawRect (aVerticalArea); // Paint horizontal stripes. Rectangle aStripeArea ( Point (mnHorizontalBorder,0), Size(mnChildrenWidth,0)); StripeList::const_iterator iStripe; for (iStripe=maStripeList.begin(); iStripe!=maStripeList.end(); iStripe++) { aStripeArea.Top() = iStripe->first; aStripeArea.Bottom() = iStripe->second; if (aStripeArea.Bottom() < 0) continue; if (aStripeArea.Top() >= aSize.Height()) break; DrawRect (aStripeArea); } SetLineColor (aOriginalLineColor); SetFillColor (aOriginalFillColor); } void SubToolPanel::Resize (void) { ::Window::Resize(); mbIsRearrangePending = true; mbIsLayoutPending = true; } void SubToolPanel::RequestResize (void) { mbIsRearrangePending = true; mbIsLayoutPending = true; Invalidate(); } Size SubToolPanel::GetPreferredSize (void) { return GetRequiredSize(); } sal_Int32 SubToolPanel::GetPreferredWidth (sal_Int32 ) { return GetPreferredSize().Width(); } sal_Int32 SubToolPanel::GetPreferredHeight (sal_Int32 ) { return GetPreferredSize().Height(); } bool SubToolPanel::IsResizable (void) { return true; } ::Window* SubToolPanel::GetWindow (void) { return this; } sal_Int32 SubToolPanel::GetMinimumWidth (void) { return TreeNode::GetMinimumWidth(); } void SubToolPanel::ExpandControl ( TreeNode* pControl, bool bExpansionState) { // Toggle expand status. pControl->Expand (bExpansionState); Rearrange (); Invalidate (); } /** This control shows an expansion bar for every control and in a separate area below that expansion area it shows all controls each with its title bar. When there is not enough space then show a scroll bar in the control area. */ void SubToolPanel::Rearrange (void) { Size aRequiredSize (GetRequiredSize()); if (aRequiredSize.Width()>0 && aRequiredSize.Height()>0) { Size aAvailableSize (GetOutputSizePixel()); // Make the children at least as wide as the sub tool panel. if (aRequiredSize.Width() < aAvailableSize.Width()) aRequiredSize.Width() = aAvailableSize.Width(); mnChildrenWidth = -2*mnHorizontalBorder; mnChildrenWidth += aAvailableSize.Width(); LayoutChildren(); mbIsRearrangePending = false; } } Size SubToolPanel::GetRequiredSize (void) { // First determine the width of the children. This is the maximum of // the current window width and the individual minimum widths of the // children. int nChildrenWidth (GetSizePixel().Width()); unsigned int nCount = mpControlContainer->GetControlCount(); unsigned int nIndex; for (nIndex=0; nIndexGetControl (nIndex); int nMinimumWidth (pChild->GetMinimumWidth()); if (nMinimumWidth > nChildrenWidth) nChildrenWidth = nMinimumWidth; } // Determine the accumulated width of all children when scaled to the // minimum width. nChildrenWidth -= 2*mnHorizontalBorder; Size aTotalSize (nChildrenWidth, 2*mnVerticalBorder + (nCount-1) * mnVerticalGap); for (nIndex=0; nIndexGetControl (nIndex); sal_Int32 nHeight = pChild->GetPreferredHeight(nChildrenWidth); aTotalSize.Height() += nHeight; } return aTotalSize; } sal_Int32 SubToolPanel::LayoutChildren (void) { // Determine vertical space that can be distributed to sizable children. unsigned int nCount (mpControlContainer->GetControlCount()); unsigned int nResizableCount = 0; int nAvailableHeight = GetSizePixel().Height() - 2*mnVerticalBorder; unsigned int nIndex; for (nIndex=0; nIndexGetControl (nIndex); int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth); if (pChild->IsResizable()) nResizableCount++; else nAvailableHeight -= nControlHeight; } maStripeList.clear(); Point aPosition (0,0); aPosition.X() += mnHorizontalBorder; maStripeList.push_back( ::std::pair( aPosition.Y(), aPosition.Y() + mnVerticalBorder - 1)); aPosition.Y() += mnVerticalBorder; // Place the controls one over the other. for (nIndex=0; nIndex 0) { maStripeList.push_back( ::std::pair( aPosition.Y(), aPosition.Y() + mnVerticalGap - 1)); aPosition.Y() += mnVerticalGap; } TreeNode* pChild = mpControlContainer->GetControl (nIndex); int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth); if (pChild->IsResizable()) { nControlHeight = nAvailableHeight / nResizableCount; nResizableCount--; } nAvailableHeight -= nControlHeight; pChild->GetWindow()->SetPosSizePixel( aPosition, Size(mnChildrenWidth, nControlHeight)); aPosition.Y() += nControlHeight; } // If the children do not cover their parent window completely // (regarding the height) we put a filler below that is responsible for // painting the remaining space. int nWindowHeight = GetSizePixel().Height(); if (aPosition.Y() < nWindowHeight) { maWindowFiller.SetPosSizePixel ( aPosition, Size(mnChildrenWidth, nWindowHeight-aPosition.Y())); maStripeList.push_back( ::std::pair( aPosition.Y(), nWindowHeight-1)); // maScrollWindowFiller.Show(); aPosition.Y() = nWindowHeight; } else maWindowFiller.Hide(); aPosition.Y() += mnVerticalBorder; mbIsLayoutPending = false; return aPosition.Y(); } IMPL_LINK(SubToolPanel, WindowEventListener, VclSimpleEvent*, pEvent) { if (pEvent!=NULL && pEvent->ISA(VclWindowEvent)) { VclWindowEvent* pWindowEvent = static_cast(pEvent); switch (pWindowEvent->GetId()) { case VCLEVENT_WINDOW_SHOW: case VCLEVENT_WINDOW_HIDE: case VCLEVENT_WINDOW_ACTIVATE: case VCLEVENT_WINDOW_RESIZE: RequestResize(); break; } } return 0; } ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SubToolPanel::CreateAccessibleObject ( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& ) { return new ::accessibility::AccessibleTreeNode ( *this, ::rtl::OUString::createFromAscii("Sub Task Panel"), ::rtl::OUString::createFromAscii("Sub Task Panel"), ::com::sun::star::accessibility::AccessibleRole::PANEL); } } } // end of namespace ::sd::toolpanel