diff options
Diffstat (limited to 'sd/source/ui/toolpanel/ScrollPanel.cxx')
-rwxr-xr-x | sd/source/ui/toolpanel/ScrollPanel.cxx | 834 |
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 |