office-gobmx/sd/source/ui/toolpanel/SubToolPanel.cxx
Rüdiger Timm 7d75e96c57 INTEGRATION: CWS components1 (1.8.14); FILE MERGED
2007/01/25 15:22:45 af 1.8.14.2: RESYNC: (1.8-1.9); FILE MERGED
2007/01/24 17:48:59 af 1.8.14.1: #i68075# The click handler can now be supplied along with a control.
2007-04-03 15:20:22 +00:00

459 lines
12 KiB
C++

/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SubToolPanel.cxx,v $
*
* $Revision: 1.10 $
*
* last change: $Author: rt $ $Date: 2007-04-03 16:20:22 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
************************************************************************/
// 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"
#ifndef _SV_DECOVIEW_HXX
#include <vcl/decoview.hxx>
#endif
#include <vcl/svapp.hxx>
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<nCount; nIndex++)
{
TitledControl* pControl = static_cast<TitledControl*>(
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<TreeNode> 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<TreeNode> 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<TreeNode> 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; nIndex<nCount; nIndex++)
{
TreeNode* pChild = mpControlContainer->GetControl (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; nIndex<nCount; nIndex++)
{
TreeNode* pChild = mpControlContainer->GetControl (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; nIndex<nCount; nIndex++)
{
TreeNode* pChild = mpControlContainer->GetControl (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<int,int>(
aPosition.Y(),
aPosition.Y() + mnVerticalBorder - 1));
aPosition.Y() += mnVerticalBorder;
// Place the controls one over the other.
for (nIndex=0; nIndex<nCount; nIndex++)
{
if (nIndex > 0)
{
maStripeList.push_back( ::std::pair<int,int>(
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<int,int>(
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<VclWindowEvent*>(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