summaryrefslogtreecommitdiff
path: root/sd/source/ui/toolpanel/ScrollPanel.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/toolpanel/ScrollPanel.cxx')
-rwxr-xr-xsd/source/ui/toolpanel/ScrollPanel.cxx834
1 files changed, 834 insertions, 0 deletions
diff --git a/sd/source/ui/toolpanel/ScrollPanel.cxx b/sd/source/ui/toolpanel/ScrollPanel.cxx
new file mode 100755
index 000000000000..6b10ed889424
--- /dev/null
+++ b/sd/source/ui/toolpanel/ScrollPanel.cxx
@@ -0,0 +1,834 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/ScrollPanel.hxx"
+
+#include "taskpane/ControlContainer.hxx"
+#include "TaskPaneFocusManager.hxx"
+#include "taskpane/TitledControl.hxx"
+#include "AccessibleScrollPanel.hxx"
+
+#include <vcl/svapp.hxx>
+#include <svtools/valueset.hxx>
+
+namespace sd { namespace toolpanel {
+
+ScrollPanel::ScrollPanel (
+ TreeNode* pParent)
+ : Control (pParent->GetWindow(), WB_DIALOGCONTROL),
+ TreeNode(pParent),
+ maScrollWindow(this, WB_DIALOGCONTROL),
+ maVerticalScrollBar(this, WB_VERT),
+ maHorizontalScrollBar(this, WB_HORZ),
+ maScrollBarFiller(this),
+ maScrollWindowFiller(&maScrollWindow),
+ mbIsRearrangePending(true),
+ mbIsLayoutPending(true),
+ mnChildrenWidth(0),
+ mnVerticalBorder(2),
+ mnVerticalGap(3),
+ mnHorizontalBorder(2)
+{
+ Construct();
+}
+
+ScrollPanel::ScrollPanel (
+ ::Window& i_rParentWindow)
+ : Control (&i_rParentWindow, WB_DIALOGCONTROL),
+ TreeNode(NULL),
+ maScrollWindow(this, WB_DIALOGCONTROL),
+ maVerticalScrollBar(this, WB_VERT),
+ maHorizontalScrollBar(this, WB_HORZ),
+ maScrollBarFiller(this),
+ maScrollWindowFiller(&maScrollWindow),
+ mbIsRearrangePending(true),
+ mbIsLayoutPending(true),
+ mnChildrenWidth(0),
+ mnVerticalBorder(2),
+ mnVerticalGap(3),
+ mnHorizontalBorder(2)
+{
+ Construct();
+}
+
+void ScrollPanel::Construct()
+{
+ 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());
+ maScrollWindow.SetBackground(Wallpaper());
+ maScrollWindowFiller.SetBackground(
+ Application::GetSettings().GetStyleSettings().GetWindowColor());
+
+ maScrollWindow.Show();
+
+ // Initialize the scroll bars.
+ maVerticalScrollBar.SetScrollHdl (
+ LINK(this, ScrollPanel, ScrollBarHandler));
+ maVerticalScrollBar.EnableDrag (TRUE);
+ maHorizontalScrollBar.SetScrollHdl (
+ LINK(this, ScrollPanel, ScrollBarHandler));
+ maHorizontalScrollBar.EnableDrag (TRUE);
+}
+
+
+
+
+ScrollPanel::~ScrollPanel (void)
+{
+ sal_uInt32 nCount = mpControlContainer->GetControlCount();
+ for (sal_uInt32 nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pNode = mpControlContainer->GetControl(nIndex);
+ TreeNode* pControl = pNode;
+ // When the node has been created as TitledControl then use its
+ // control instead of pNode directly.
+ TitledControl* pTitledControl = static_cast<TitledControl*>(pNode);
+ if (pTitledControl != NULL)
+ pControl = pTitledControl->GetControl();
+
+ // Remove this object as listener from the control.
+ if (pControl != NULL && pControl->GetWindow()!=NULL)
+ {
+ pControl->GetWindow()->RemoveEventListener(
+ LINK(this,ScrollPanel,WindowEventListener));
+ }
+ }
+ mpControlContainer->DeleteChildren();
+}
+
+
+
+
+TitledControl* ScrollPanel::AddControl (
+ ::std::auto_ptr<TreeNode> pControl,
+ const String& rTitle,
+ ULONG nHelpId)
+{
+ // 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->GetTitleBar()->SetHelpId(nHelpId);
+
+ AddControl(::std::auto_ptr<TreeNode>(pTitledControl));
+
+ return pTitledControl;
+}
+
+
+
+
+void ScrollPanel::AddControl (::std::auto_ptr<TreeNode> pControl)
+{
+ if (pControl.get() != NULL)
+ {
+ // Add a window event listener which does two things:
+ // 1. Listen for controls being shown or hidden so that the layout
+ // can be adapted.
+ // 2. Track selection changes in order to make the selected elements
+ // visible.
+ const Link aWindowListener(LINK(this,ScrollPanel,WindowEventListener));
+ OSL_ASSERT(pControl->GetWindow()!=NULL);
+ pControl->GetWindow()->AddEventListener(aWindowListener);
+
+ TitledControl* pTitledControl = dynamic_cast<TitledControl*>(pControl.get());
+ if (pTitledControl != NULL)
+ {
+ OSL_ASSERT(pTitledControl->GetControl()!=NULL);
+ OSL_ASSERT(pTitledControl->GetControl()->GetWindow()!=NULL);
+ pTitledControl->GetControl()->GetWindow()->AddEventListener(aWindowListener);
+ }
+
+ FocusManager& rFocusManager (FocusManager::Instance());
+ int nControlCount (mpControlContainer->GetControlCount());
+ // Replace the old links for cycling between first and last child by
+ // current ones.
+ if (nControlCount > 0)
+ {
+ ::Window* pFirst = mpControlContainer->GetControl(0)->GetWindow();
+ ::Window* pLast = mpControlContainer->GetControl(nControlCount-1)->GetWindow();
+ rFocusManager.RemoveLinks(pFirst,pLast);
+ rFocusManager.RemoveLinks(pLast,pFirst);
+
+ rFocusManager.RegisterLink(pFirst,pControl->GetWindow(), KEY_UP);
+ rFocusManager.RegisterLink(pControl->GetWindow(),pFirst, KEY_DOWN);
+ }
+
+
+ // 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 (nControlCount == 0)
+ rFocusManager.RegisterDownLink(GetParent(), pControl->GetWindow());
+ rFocusManager.RegisterUpLink(pControl->GetWindow(), GetParent());
+
+ pControl->GetWindow()->SetParent(&maScrollWindow);
+ mpControlContainer->AddControl (pControl);
+ mpControlContainer->SetExpansionState(
+ mpControlContainer->GetControlCount()-1,
+ ControlContainer::ES_EXPAND);
+ }
+}
+
+
+
+
+void ScrollPanel::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 (maScrollWindow.GetLineColor());
+ Color aOriginalFillColor (maScrollWindow.GetFillColor());
+
+ maScrollWindow.SetLineColor ();
+ maScrollWindow.SetFillColor (
+ GetSettings().GetStyleSettings().GetWindowColor());
+
+ Size aSize (maScrollWindow.GetOutputSizePixel());
+ // Paint left and right vertical border.
+ Rectangle aVerticalArea (
+ Point(0,0),
+ Size(mnHorizontalBorder,aSize.Height()));
+ maScrollWindow.DrawRect (aVerticalArea);
+ aVerticalArea.Right() += mnHorizontalBorder + mnChildrenWidth - 1;
+ aVerticalArea.Left() = aVerticalArea.Right() + mnHorizontalBorder;
+ maScrollWindow.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;
+ maScrollWindow.DrawRect (aStripeArea);
+ }
+
+ maScrollWindow.SetLineColor (aOriginalLineColor);
+ maScrollWindow.SetFillColor (aOriginalFillColor);
+}
+
+
+
+
+void ScrollPanel::Resize (void)
+{
+ ::Window::Resize();
+ mbIsRearrangePending = true;
+ mbIsLayoutPending = true;
+}
+
+
+
+
+void ScrollPanel::RequestResize (void)
+{
+ mbIsRearrangePending = true;
+ mbIsLayoutPending = true;
+ Invalidate();
+}
+
+
+
+
+Size ScrollPanel::GetPreferredSize (void)
+{
+ return GetRequiredSize();
+}
+
+
+
+
+sal_Int32 ScrollPanel::GetPreferredWidth (sal_Int32 )
+{
+ return GetPreferredSize().Width();
+}
+
+
+
+
+sal_Int32 ScrollPanel::GetPreferredHeight (sal_Int32 )
+{
+ return GetPreferredSize().Height();
+}
+
+
+
+
+bool ScrollPanel::IsResizable (void)
+{
+ return true;
+}
+
+
+
+
+::Window* ScrollPanel::GetWindow (void)
+{
+ return this;
+}
+
+
+
+
+sal_Int32 ScrollPanel::GetMinimumWidth (void)
+{
+ return TreeNode::GetMinimumWidth();
+}
+
+
+
+
+void ScrollPanel::ExpandControl (
+ TreeNode* pControl,
+ bool bExpansionState)
+{
+ // Toggle expand status.
+ pControl->Expand (bExpansionState);
+
+ Rearrange ();
+ Invalidate ();
+}
+
+
+
+
+bool ScrollPanel::IsVerticalScrollBarVisible (void) const
+{
+ return maVerticalScrollBar.IsReallyVisible();
+}
+
+
+
+
+bool ScrollPanel::IsHorizontalScrollBarVisible (void) const
+{
+ return maHorizontalScrollBar.IsReallyVisible();
+}
+
+
+
+
+ScrollBar& ScrollPanel::GetVerticalScrollBar (void)
+{
+ return maVerticalScrollBar;
+}
+
+
+
+
+ScrollBar& ScrollPanel::GetHorizontalScrollBar (void)
+{
+ return maHorizontalScrollBar;
+}
+
+
+
+
+/** 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 ScrollPanel::Rearrange (void)
+{
+ Size aRequiredSize (GetRequiredSize());
+ if (aRequiredSize.Width()>0 && aRequiredSize.Height()>0)
+ {
+ Size aAvailableSize (SetupScrollBars (aRequiredSize));
+ maScrollWindow.SetPosSizePixel(
+ Point(0,0),
+ aAvailableSize);
+
+ // Make the children at least as wide as the sub tool panel.
+ if (aRequiredSize.Width() < aAvailableSize.Width())
+ aRequiredSize.Width() = aAvailableSize.Width();
+ mnChildrenWidth = -2*mnHorizontalBorder;
+ if (maHorizontalScrollBar.IsVisible())
+ mnChildrenWidth += aRequiredSize.Width();
+ else
+ mnChildrenWidth += aAvailableSize.Width();
+
+ sal_Int32 nChildrenHeight (LayoutChildren());
+ maVerticalScrollBar.SetRangeMax (
+ nChildrenHeight + mnVerticalBorder);
+
+ mbIsRearrangePending = false;
+ }
+}
+
+
+
+
+Size ScrollPanel::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 ScrollPanel::LayoutChildren (void)
+{
+ maStripeList.clear();
+
+ Point aPosition (maScrollOffset);
+ 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.
+ unsigned int nCount (mpControlContainer->GetControlCount());
+ for (unsigned int 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);
+ 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 = maScrollWindow.GetSizePixel().Height();
+ if (aPosition.Y() < nWindowHeight)
+ {
+ maScrollWindowFiller.SetPosSizePixel (
+ aPosition,
+ Size(mnChildrenWidth, nWindowHeight-aPosition.Y()));
+ maStripeList.push_back( ::std::pair<int,int>(
+ aPosition.Y(),
+ nWindowHeight-1));
+ // maScrollWindowFiller.Show();
+ aPosition.Y() = nWindowHeight;
+ }
+ else
+ maScrollWindowFiller.Hide();
+
+ aPosition.Y() += mnVerticalBorder;
+ mbIsLayoutPending = false;
+
+ return aPosition.Y()-maScrollOffset.Y();
+}
+
+
+
+
+Size ScrollPanel::SetupScrollBars (const Size& rRequiredSize)
+{
+ Size aWindowSize (GetSizePixel());
+ Size aScrollBarSize (
+ maVerticalScrollBar.GetSizePixel().Width(),
+ maHorizontalScrollBar.GetSizePixel().Height());
+ Size aRemainingSize (aWindowSize);
+
+ // Determine which scroll bars have to be shown.
+ bool bShowHorizontal = false;
+ if (rRequiredSize.Width() > aWindowSize.Width())
+ bShowHorizontal = true;
+ bool bShowVertical = false;
+ if (rRequiredSize.Height() > aWindowSize.Height())
+ bShowVertical = true;
+ // Showing one scroll bar may reduce the available size so that the
+ // other one has to be shown as well.
+ if (bShowHorizontal && ! bShowVertical)
+ {
+ if ((rRequiredSize.Height() + aScrollBarSize.Height())
+ > aWindowSize.Height())
+ bShowVertical = true;
+ }
+ else if (bShowVertical && ! bShowHorizontal)
+ {
+ if (GetMinimumWidth() + aScrollBarSize.Width() > aWindowSize.Width())
+ bShowHorizontal = true;
+ }
+
+ // Setup the scroll bars.
+ aRemainingSize.Width()
+ = SetupVerticalScrollBar (bShowVertical, rRequiredSize.Height());
+ aRemainingSize.Height()
+ = SetupHorizontalScrollBar (bShowHorizontal, rRequiredSize.Width());
+
+ // Place the filler.
+ if (bShowHorizontal && bShowVertical)
+ {
+ maScrollBarFiller.SetPosSizePixel (
+ Point(aWindowSize.Width(), aWindowSize.Height()),
+ aScrollBarSize);
+ maScrollBarFiller.Show();
+ }
+ else
+ maScrollBarFiller.Hide();
+
+
+ return aRemainingSize;
+}
+
+
+
+
+sal_Int32 ScrollPanel::SetupVerticalScrollBar (bool bShow, sal_Int32 nRange)
+{
+ Size aScrollBarSize (
+ maVerticalScrollBar.GetSizePixel().Width(),
+ maHorizontalScrollBar.GetSizePixel().Height());
+ Size aWindowSize (GetOutputSizePixel());
+ sal_Int32 nRemainingWidth (aWindowSize.Width());
+
+ // Setup the verical scroll bar.
+ if (bShow)
+ {
+ int nWidth = aScrollBarSize.Width();
+ int nHeight = aWindowSize.Height();
+ maVerticalScrollBar.SetPosSizePixel(
+ Point(aWindowSize.Width()-nWidth,0),
+ Size(nWidth, nHeight));
+ maVerticalScrollBar.Show();
+
+ // Set the scroll bar range and thumb size.
+ maVerticalScrollBar.SetRangeMin (0);
+ maVerticalScrollBar.SetRangeMax (
+ nRange + 2*mnVerticalBorder);
+ maVerticalScrollBar.SetVisibleSize (aWindowSize.Height());
+ // Make page size approx. 10% of visible area.
+ maVerticalScrollBar.SetLineSize (aWindowSize.Height()/10);
+ // Make page size approx. 100% of visible area.
+ maVerticalScrollBar.SetPageSize (aWindowSize.Height());
+ // Make sure that thumb is inside the valid range.
+ maVerticalScrollBar.SetThumbPos(-maScrollOffset.Y());
+ long nMinPos = maVerticalScrollBar.GetRangeMin();
+ if (maVerticalScrollBar.GetThumbPos() < nMinPos)
+ maVerticalScrollBar.SetThumbPos(nMinPos);
+ long nMaxPos = maVerticalScrollBar.GetRangeMax()
+ - maVerticalScrollBar.GetVisibleSize();
+ if (maVerticalScrollBar.GetThumbPos() >= nMaxPos)
+ maVerticalScrollBar.SetThumbPos(nMaxPos);
+ // Set offset to match thumb pos.
+ maScrollOffset.Y() = -maVerticalScrollBar.GetThumbPos();
+
+ nRemainingWidth -= aScrollBarSize.Width();
+ }
+ else
+ {
+ maVerticalScrollBar.Hide();
+ maScrollOffset.Y() = 0;
+ }
+
+ return nRemainingWidth;
+}
+
+
+
+
+sal_Int32 ScrollPanel::SetupHorizontalScrollBar (bool bShow, sal_Int32 nRange)
+{
+ Size aScrollBarSize (
+ maVerticalScrollBar.GetSizePixel().Width(),
+ maHorizontalScrollBar.GetSizePixel().Height());
+ Size aWindowSize (GetOutputSizePixel());
+ sal_Int32 nRemainingHeight (aWindowSize.Height());
+
+ // Setup the horizontal scroll bar.
+ if (bShow)
+ {
+ int nHeight = aScrollBarSize.Height();
+ int nWidth = GetOutputSizePixel().Width();
+ maHorizontalScrollBar.SetPosSizePixel(
+ Point(0, aWindowSize.Height()-nHeight),
+ Size(nWidth,nHeight));
+ maHorizontalScrollBar.Show();
+
+ // Set the scroll bar range and thumb size.
+ maHorizontalScrollBar.SetRangeMin (0);
+ maHorizontalScrollBar.SetRangeMax (
+ nRange + 2*mnHorizontalBorder);
+ maHorizontalScrollBar.SetVisibleSize (aWindowSize.Width());
+ // Make page size approx. 5% of visible area.
+ maHorizontalScrollBar.SetLineSize (aWindowSize.Width()/20+1);
+ // Make page size approx. 50% of visible area.
+ maHorizontalScrollBar.SetPageSize (aWindowSize.Width()/2+1);
+ // Make sure that thumb is inside the valid range.
+ maHorizontalScrollBar.SetThumbPos(-maScrollOffset.X());
+ long nMinPos = maHorizontalScrollBar.GetRangeMin();
+ if (maHorizontalScrollBar.GetThumbPos() < nMinPos)
+ maHorizontalScrollBar.SetThumbPos(nMinPos);
+ long nMaxPos = maHorizontalScrollBar.GetRangeMax()
+ - maHorizontalScrollBar.GetVisibleSize();
+ if (maHorizontalScrollBar.GetThumbPos() >= nMaxPos)
+ maHorizontalScrollBar.SetThumbPos(nMaxPos);
+ // Set offset to match thumb pos.
+ maScrollOffset.X() = -maHorizontalScrollBar.GetThumbPos();
+
+ nRemainingHeight -= aScrollBarSize.Height();
+ }
+ else
+ {
+ maHorizontalScrollBar.Hide();
+ maScrollOffset.X() = 0;
+ }
+
+ return nRemainingHeight;
+}
+
+
+IMPL_LINK(ScrollPanel, ScrollBarHandler, ScrollBar*, EMPTYARG)
+{
+ maScrollOffset.X() -= maHorizontalScrollBar.GetDelta();
+ maScrollOffset.Y() -= maVerticalScrollBar.GetDelta();
+
+ // Scrolling is done by moving the child windows up or down.
+ mbIsLayoutPending = true;
+ Invalidate();
+ // LayoutChildren();
+
+ return 0;
+}
+
+
+
+
+long ScrollPanel::Notify( NotifyEvent& rNEvt )
+{
+ long nRet = FALSE;
+ if( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ // note: dynamic_cast is not possible as GetData() returns a void*
+ CommandEvent* pCmdEvent = reinterpret_cast< CommandEvent* >(rNEvt.GetData());
+ DBG_ASSERT( pCmdEvent!=0 &&
+ ( pCmdEvent->IsMouseEvent() == TRUE ||
+ pCmdEvent->IsMouseEvent() == FALSE ),
+ "Invalid CommandEvent" );
+ if (pCmdEvent)
+ switch (pCmdEvent->GetCommand())
+ {
+ case COMMAND_WHEEL:
+ case COMMAND_STARTAUTOSCROLL:
+ case COMMAND_AUTOSCROLL:
+ {
+ nRet = HandleScrollCommand (*pCmdEvent, &maHorizontalScrollBar, &maVerticalScrollBar);
+ break;
+ }
+ }
+ }
+
+ if( ! nRet )
+ nRet = ::Window::Notify( rNEvt );
+
+ return nRet;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> ScrollPanel::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ return new ::accessibility::AccessibleScrollPanel (
+ *this,
+ ::rtl::OUString::createFromAscii("Scroll Panel"),
+ ::rtl::OUString::createFromAscii("Scroll Panel"));
+}
+
+
+
+
+void ScrollPanel::MakeRectangleVisible (
+ Rectangle& aRectangle,
+ ::Window* pWindow)
+{
+ if (maVerticalScrollBar.IsVisible() && aRectangle.GetWidth()>0 && aRectangle.GetHeight()>0)
+ {
+ const Rectangle aRelativeBox (pWindow->GetWindowExtentsRelative(&maScrollWindow));
+
+ aRectangle.Move(
+ -maScrollOffset.X() + aRelativeBox.Left(),
+ -maScrollOffset.Y() + aRelativeBox.Top());
+
+ const int nVisibleHeight (maVerticalScrollBar.GetVisibleSize());
+ const int nVisibleTop (maVerticalScrollBar.GetThumbPos());
+ if (aRectangle.Bottom() >= nVisibleTop+nVisibleHeight)
+ maVerticalScrollBar.DoScroll(aRectangle.Bottom() - nVisibleHeight);
+ else if (aRectangle.Top() < nVisibleTop)
+ maVerticalScrollBar.DoScroll(aRectangle.Top());
+ }
+}
+
+
+
+
+IMPL_LINK(ScrollPanel,WindowEventListener,VclSimpleEvent*,pEvent)
+{
+ VclWindowEvent* pWindowEvent = dynamic_cast<VclWindowEvent*>(pEvent);
+ if (pWindowEvent != NULL)
+ {
+ switch (pWindowEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_KEYUP:
+ case VCLEVENT_WINDOW_MOUSEBUTTONUP:
+ {
+ // Make the currently selected item visible.
+ ValueSet* pControl = dynamic_cast<ValueSet*>(pWindowEvent->GetWindow());
+ if (pControl != NULL)
+ {
+ // Get the bounding box of the currently selected item
+ // and enlarge this so that the selection frame is
+ // inside as well.
+ Rectangle aBox (pControl->GetItemRect(pControl->GetSelectItemId()));
+ aBox.Top()-=4;
+ aBox.Bottom()+=4;
+
+ MakeRectangleVisible(aBox, pControl);
+ }
+ }
+ break;
+
+ case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
+ {
+ // Make the item under the mouse visible. We need this case
+ // for right clicks that open context menus. For these we
+ // only get the mouse down event. The following mouse up
+ // event is sent to the context menu.
+ ValueSet* pControl = dynamic_cast<ValueSet*>(pWindowEvent->GetWindow());
+ if (pControl != NULL)
+ {
+ // Get the bounding box of the item at the mouse
+ // position and enlarge this so that the selection frame
+ // is inside as well.
+ MouseEvent* pMouseEvent
+ = reinterpret_cast<MouseEvent*>(pWindowEvent->GetData());
+ if (pMouseEvent != NULL)
+ {
+ Point aPosition (pMouseEvent->GetPosPixel());
+ Rectangle aBox (pControl->GetItemRect(pControl->GetItemId(aPosition)));
+ aBox.Top()-=4;
+ aBox.Bottom()+=4;
+
+ MakeRectangleVisible(aBox, pControl);
+ }
+ }
+ }
+ break;
+
+
+ case VCLEVENT_WINDOW_GETFOCUS:
+ {
+ // Move title bars into the visible area when they get the
+ // focus (::Window wise their enclosing TitledControl gets
+ // the focus.)
+ TitledControl* pTitledControl = dynamic_cast<TitledControl*>(pWindowEvent->GetWindow());
+ if (pTitledControl!=NULL && pTitledControl->GetTitleBar()!=NULL)
+ {
+ ::Window* pTitleBarWindow = pTitledControl->GetTitleBar()->GetWindow();
+ Rectangle aBox(pTitleBarWindow->GetPosPixel(),pTitleBarWindow->GetSizePixel());
+ MakeRectangleVisible(
+ aBox,
+ pTitleBarWindow);
+ }
+ }
+ break;
+
+ case VCLEVENT_WINDOW_SHOW:
+ case VCLEVENT_WINDOW_HIDE:
+ case VCLEVENT_WINDOW_ACTIVATE:
+ case VCLEVENT_WINDOW_RESIZE:
+ // Rearrange the children of the scroll panel when one of
+ // the children changes its size or visibility.
+ RequestResize();
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+
+} } // end of namespace ::sd::toolpanel