summaryrefslogtreecommitdiff
path: root/svtools/source/control/scrwin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/control/scrwin.cxx')
-rw-r--r--svtools/source/control/scrwin.cxx603
1 files changed, 603 insertions, 0 deletions
diff --git a/svtools/source/control/scrwin.cxx b/svtools/source/control/scrwin.cxx
new file mode 100644
index 000000000000..10ef086ed9fd
--- /dev/null
+++ b/svtools/source/control/scrwin.cxx
@@ -0,0 +1,603 @@
+/*************************************************************************
+ *
+ * $RCSfile: scrwin.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:58:57 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SVT_SCRWIN_CXX
+#include <scrwin.hxx>
+
+//===================================================================
+
+void ScrollableWindow::ImpInitialize( ScrollableWindowFlags nFlags )
+{
+ bHandleDragging = (BOOL) ( nFlags & SCRWIN_THUMBDRAGGING );
+ bVCenter = (nFlags & SCRWIN_VCENTER) == SCRWIN_VCENTER;
+ bHCenter = (nFlags & SCRWIN_HCENTER) == SCRWIN_HCENTER;
+ bScrolling = FALSE;
+
+ // set the handlers for the scrollbars
+ aVScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
+ aHScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
+ aVScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
+ aHScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
+
+ nColumnPixW = nLinePixH = GetSettings().GetStyleSettings().GetScrollBarSize();
+}
+
+//-------------------------------------------------------------------
+
+ScrollableWindow::ScrollableWindow( Window* pParent, WinBits nBits,
+ ScrollableWindowFlags nFlags ) :
+ Window( pParent, WinBits(nBits|WB_CLIPCHILDREN) ),
+ aVScroll( this, WinBits(WB_VSCROLL | WB_DRAG) ),
+ aHScroll( this, WinBits(WB_HSCROLL | WB_DRAG) ),
+ aCornerWin( this )
+{
+ ImpInitialize( nFlags );
+}
+
+//-------------------------------------------------------------------
+
+ScrollableWindow::ScrollableWindow( Window* pParent, const ResId& rId,
+ ScrollableWindowFlags nFlags ) :
+ Window( pParent, rId ),
+ aVScroll( this, WinBits(WB_VSCROLL | WB_DRAG) ),
+ aHScroll( this, WinBits(WB_HSCROLL | WB_DRAG) ),
+ aCornerWin( this )
+{
+ ImpInitialize( nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollableWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
+ (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
+ (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
+ {
+ ScrollBar* pHScrBar;
+ ScrollBar* pVScrBar;
+ if ( aHScroll.IsVisible() )
+ pHScrBar = &aHScroll;
+ else
+ pHScrBar = NULL;
+ if ( aVScroll.IsVisible() )
+ pVScrBar = &aVScroll;
+ else
+ pVScrBar = NULL;
+ if ( HandleScrollCommand( rCEvt, pHScrBar, pVScrBar ) )
+ return;
+ }
+
+ Window::Command( rCEvt );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ Resize();
+ Invalidate();
+ }
+
+ Window::DataChanged( rDCEvt );
+}
+
+//-------------------------------------------------------------------
+
+Size __EXPORT ScrollableWindow::GetOutputSizePixel() const
+{
+ Size aSz( Window::GetOutputSizePixel() );
+
+ long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aHScroll.IsVisible() )
+ aSz.Height() -= nTmp;
+ if ( aVScroll.IsVisible() )
+ aSz.Width() -= nTmp;
+ return aSz;
+}
+
+//-------------------------------------------------------------------
+
+Size ScrollableWindow::GetOutputSize() const
+{
+ return PixelToLogic( GetOutputSizePixel() );
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( ScrollableWindow, EndScrollHdl, ScrollBar *, pScroll )
+{
+ // notify the start of scrolling, if not already scrolling
+ if ( !bScrolling )
+ StartScroll(), bScrolling = TRUE;
+
+ // get the delta in logic coordinates
+ Size aDelta( PixelToLogic( Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
+
+ // scroll the window, if this is not already done
+ if ( !bHandleDragging )
+ {
+ if ( pScroll == &aHScroll )
+ Scroll( aDelta.Width(), 0 );
+ else
+ Scroll( 0, aDelta.Height() );
+ }
+
+ // notify the end of scrolling
+ bScrolling = FALSE;
+ EndScroll( aDelta.Width(), aDelta.Height() );
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( ScrollableWindow, ScrollHdl, ScrollBar *, pScroll )
+{
+ // notify the start of scrolling, if not already scrolling
+ if ( !bScrolling )
+ StartScroll(), bScrolling = TRUE;
+
+ if ( bHandleDragging )
+ {
+ // get the delta in logic coordinates
+ Size aDelta( PixelToLogic(
+ Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
+ if ( pScroll == &aHScroll )
+ Scroll( aDelta.Width(), 0 );
+ else
+ Scroll( 0, aDelta.Height() );
+ }
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::Resize()
+{
+ // get the new output-size in pixel
+ Size aOutPixSz = Window::GetOutputSizePixel();
+
+ // determine the size of the output-area and if we need scrollbars
+ const long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ BOOL bVVisible = FALSE; // by default no vertical-ScrollBar
+ BOOL bHVisible = FALSE; // by default no horizontal-ScrollBar
+ BOOL bChanged; // determines if a visiblility was changed
+ do
+ {
+ bChanged = FALSE;
+
+ // does we need a vertical ScrollBar
+ if ( aOutPixSz.Width() < aTotPixSz.Width() && !bHVisible )
+ { bHVisible = TRUE;
+ aOutPixSz.Height() -= nScrSize;
+ bChanged = TRUE;
+ }
+
+ // does we need a horizontal ScrollBar
+ if ( aOutPixSz.Height() < aTotPixSz.Height() && !bVVisible )
+ { bVVisible = TRUE;
+ aOutPixSz.Width() -= nScrSize;
+ bChanged = TRUE;
+ }
+
+ }
+ while ( bChanged ); // until no visibility has changed
+
+ // store the old offset and map-mode
+ MapMode aMap( GetMapMode() );
+ Point aOldPixOffset( aPixOffset );
+
+ // justify (right/bottom borders should never exceed the virtual window)
+ Size aPixDelta;
+ if ( aPixOffset.X() < 0 &&
+ aPixOffset.X() + aTotPixSz.Width() < aOutPixSz.Width() )
+ aPixDelta.Width() =
+ aOutPixSz.Width() - ( aPixOffset.X() + aTotPixSz.Width() );
+ if ( aPixOffset.Y() < 0 &&
+ aPixOffset.Y() + aTotPixSz.Height() < aOutPixSz.Height() )
+ aPixDelta.Height() =
+ aOutPixSz.Height() - ( aPixOffset.Y() + aTotPixSz.Height() );
+ if ( aPixDelta.Width() || aPixDelta.Height() )
+ {
+ aPixOffset.X() += aPixDelta.Width();
+ aPixOffset.Y() += aPixDelta.Height();
+ }
+
+ // for axis without scrollbar restore the origin
+ if ( !bVVisible || !bHVisible )
+ {
+ aPixOffset = Point(
+ bHVisible
+ ? aPixOffset.X()
+ : ( bHCenter
+ ? (aOutPixSz.Width()-aTotPixSz.Width()) / 2
+ : 0 ),
+ bVVisible
+ ? aPixOffset.Y()
+ : ( bVCenter
+ ? (aOutPixSz.Height()-aTotPixSz.Height()) / 2
+ : 0 ) );
+ }
+ if ( bHVisible && !aHScroll.IsVisible() )
+ aPixOffset.X() = 0;
+ if ( bVVisible && !aVScroll.IsVisible() )
+ aPixOffset.Y() = 0;
+
+ // select the shifted map-mode
+ if ( aPixOffset != aOldPixOffset )
+ {
+ Window::SetMapMode( MapMode( MAP_PIXEL ) );
+ Window::Scroll(
+ aPixOffset.X() - aOldPixOffset.X(),
+ aPixOffset.Y() - aOldPixOffset.Y() );
+ SetMapMode( aMap );
+ }
+
+ // show or hide scrollbars
+ aVScroll.Show( bVVisible );
+ aHScroll.Show( bHVisible );
+
+ // disable painting in the corner between the scrollbars
+ if ( bVVisible && bHVisible )
+ {
+ aCornerWin.SetPosSizePixel(
+ *((Point*) &aOutPixSz), Size(nScrSize, nScrSize) );
+ aCornerWin.Show();
+ }
+ else
+ aCornerWin.Hide();
+
+ // resize scrollbars and set their ranges
+ if ( bHVisible )
+ {
+ aHScroll.SetPosSizePixel(
+ Point( 0, aOutPixSz.Height() ),
+ Size( aOutPixSz.Width(), nScrSize ) );
+ aHScroll.SetRange( Range( 0, aTotPixSz.Width() ) );
+ aHScroll.SetPageSize( aOutPixSz.Width() );
+ aHScroll.SetVisibleSize( aOutPixSz.Width() );
+ aHScroll.SetLineSize( nColumnPixW );
+ aHScroll.SetThumbPos( -aPixOffset.X() );
+ }
+ if ( bVVisible )
+ {
+ aVScroll.SetPosSizePixel(
+ Point( aOutPixSz.Width(), 0 ),
+ Size( nScrSize,aOutPixSz.Height() ) );
+ aVScroll.SetRange( Range( 0, aTotPixSz.Height() ) );
+ aVScroll.SetPageSize( aOutPixSz.Height() );
+ aVScroll.SetVisibleSize( aOutPixSz.Height() );
+ aVScroll.SetLineSize( nLinePixH );
+ aVScroll.SetThumbPos( -aPixOffset.Y() );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::StartScroll()
+{
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::EndScroll( long nDeltaX, long nDeltaY )
+{
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetMapMode( const MapMode& rNewMapMode )
+{
+ MapMode aMap( rNewMapMode );
+ aMap.SetOrigin( aMap.GetOrigin() + PixelToLogic( aPixOffset, aMap ) );
+ Window::SetMapMode( aMap );
+}
+
+//-------------------------------------------------------------------
+
+MapMode ScrollableWindow::GetMapMode() const
+{
+ MapMode aMap( Window::GetMapMode() );
+ aMap.SetOrigin( aMap.GetOrigin() - PixelToLogic( aPixOffset ) );
+ return aMap;
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetTotalSize( const Size& rNewSize )
+{
+ aTotPixSz = LogicToPixel( rNewSize );
+ ScrollableWindow::Resize();
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetVisibleSize( const Size& rNewSize )
+{
+ // get the rectangle, we wish to view
+ Rectangle aWish( Point(0, 0), LogicToPixel(rNewSize) );
+
+ // get maximum rectangle for us from our parent-window (subst our border!)
+ Rectangle aMax( Point(0, 0), GetParent()->GetOutputSizePixel() );
+ aMax.Left() -= ( Window::GetSizePixel().Width() -
+ Window::GetOutputSizePixel().Width() );
+ aMax.Bottom() -= (Window::GetSizePixel().Height() -
+ Window::GetOutputSizePixel().Height());
+
+ Size aWill( aWish.GetIntersection(aMax).GetSize() );
+ BOOL bHScroll = FALSE;
+ const long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aWill.Width() < aWish.GetSize().Width() )
+ { bHScroll = TRUE;
+ aWill.Height() =
+ Min( aWill.Height()+nScrSize, aMax.GetSize().Height() );
+ }
+ if ( aWill.Height() < aWish.GetSize().Height() )
+ aWill.Width() =
+ Min( aWill.Width()+nScrSize, aMax.GetSize().Width() );
+ if ( !bHScroll && (aWill.Width() < aWish.GetSize().Width()) )
+ aWill.Height() =
+ Min( aWill.Height()+nScrSize, aMax.GetSize().Height() );
+ Window::SetOutputSizePixel( aWill );
+}
+
+//-------------------------------------------------------------------
+
+BOOL ScrollableWindow::MakeVisible( const Rectangle& rTarget, BOOL bSloppy )
+{
+ Rectangle aTarget;
+ Rectangle aTotRect( Point(0, 0), PixelToLogic( aTotPixSz ) );
+
+ if ( bSloppy )
+ {
+ aTarget = rTarget;
+
+ // at maximum to right border
+ if ( aTarget.Right() > aTotRect.Right() )
+ {
+ long nDelta = aTarget.Right() - aTotRect.Right();
+ aTarget.Left() -= nDelta;
+ aTarget.Right() -= nDelta;
+
+ // too wide?
+ if ( aTarget.Left() < aTotRect.Left() )
+ aTarget.Left() = aTotRect.Left();
+ }
+
+ // at maximum to bottom border
+ if ( aTarget.Bottom() > aTotRect.Bottom() )
+ {
+ long nDelta = aTarget.Bottom() - aTotRect.Bottom();
+ aTarget.Top() -= nDelta;
+ aTarget.Bottom() -= nDelta;
+
+ // too high?
+ if ( aTarget.Top() < aTotRect.Top() )
+ aTarget.Top() = aTotRect.Top();
+ }
+
+ // at maximum to left border
+ if ( aTarget.Left() < aTotRect.Left() )
+ {
+ long nDelta = aTarget.Left() - aTotRect.Left();
+ aTarget.Right() -= nDelta;
+ aTarget.Left() -= nDelta;
+
+ // too wide?
+ if ( aTarget.Right() > aTotRect.Right() )
+ aTarget.Right() = aTotRect.Right();
+ }
+
+ // at maximum to top border
+ if ( aTarget.Top() < aTotRect.Top() )
+ {
+ long nDelta = aTarget.Top() - aTotRect.Top();
+ aTarget.Bottom() -= nDelta;
+ aTarget.Top() -= nDelta;
+
+ // too high?
+ if ( aTarget.Bottom() > aTotRect.Bottom() )
+ aTarget.Bottom() = aTotRect.Bottom();
+ }
+ }
+ else
+ aTarget = rTarget.GetIntersection( aTotRect );
+
+ // is the area already visible?
+ Rectangle aVisArea( GetVisibleArea() );
+ if ( aVisArea.IsInside(rTarget) )
+ return TRUE;
+
+ // is there somewhat to scroll?
+ if ( aVisArea.TopLeft() != aTarget.TopLeft() )
+ {
+ Rectangle aBox( aTarget.GetUnion(aVisArea) );
+ long nDeltaX = ( aBox.Right() - aVisArea.Right() ) +
+ ( aBox.Left() - aVisArea.Left() );
+ long nDeltaY = ( aBox.Top() - aVisArea.Top() ) +
+ ( aBox.Bottom() - aVisArea.Bottom() );
+ Scroll( nDeltaX, nDeltaY );
+ }
+
+ // determine if the target is completely visible
+ return aVisArea.GetWidth() >= aTarget.GetWidth() &&
+ aVisArea.GetHeight() >= aTarget.GetHeight();
+}
+
+//-------------------------------------------------------------------
+
+Rectangle ScrollableWindow::GetVisibleArea() const
+{
+ Point aTopLeft( PixelToLogic( Point() ) );
+ Size aSz( GetOutputSize() );
+ return Rectangle( aTopLeft, aSz );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetLineSize( ULONG nHorz, ULONG nVert )
+{
+ Size aPixSz( LogicToPixel( Size(nHorz, nVert) ) );
+ nColumnPixW = aPixSz.Width();
+ nLinePixH = aPixSz.Height();
+ aVScroll.SetLineSize( nLinePixH );
+ aHScroll.SetLineSize( nColumnPixW );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::Scroll( long nDeltaX, long nDeltaY )
+{
+ if ( !bScrolling )
+ StartScroll();
+
+ // get the delta in pixel
+ Size aDeltaPix( LogicToPixel( Size(nDeltaX, nDeltaY) ) );
+ Size aOutPixSz( GetOutputSizePixel() );
+ MapMode aMap( GetMapMode() );
+ Point aNewPixOffset( aPixOffset );
+
+ // scrolling horizontally?
+ if ( nDeltaX != 0 )
+ {
+ aNewPixOffset.X() -= aDeltaPix.Width();
+ if ( ( aOutPixSz.Width() - aNewPixOffset.X() ) > aTotPixSz.Width() )
+ aNewPixOffset.X() = - ( aTotPixSz.Width() - aOutPixSz.Width() );
+ else if ( aNewPixOffset.X() > 0 )
+ aNewPixOffset.X() = 0;
+ }
+
+ // scrolling vertically?
+ if ( nDeltaY != 0 )
+ {
+ aNewPixOffset.Y() -= aDeltaPix.Height();
+ if ( ( aOutPixSz.Height() - aNewPixOffset.Y() ) > aTotPixSz.Height() )
+ aNewPixOffset.Y() = - ( aTotPixSz.Height() - aOutPixSz.Height() );
+ else if ( aNewPixOffset.Y() > 0 )
+ aNewPixOffset.Y() = 0;
+ }
+
+ // recompute the logical scroll units
+ aDeltaPix.Width() = aPixOffset.X() - aNewPixOffset.X();
+ aDeltaPix.Height() = aPixOffset.Y() - aNewPixOffset.Y();
+ Size aDelta( PixelToLogic(aDeltaPix) );
+ nDeltaX = aDelta.Width();
+ nDeltaY = aDelta.Height();
+ aPixOffset = aNewPixOffset;
+
+ // scrolling?
+ if ( nDeltaX != 0 || nDeltaY != 0 )
+ {
+ Update();
+
+ // does the new area overlap the old one?
+ if ( Abs( (int)aDeltaPix.Height() ) < aOutPixSz.Height() ||
+ Abs( (int)aDeltaPix.Width() ) < aOutPixSz.Width() )
+ {
+ // scroll the overlapping area
+ SetMapMode( aMap );
+
+ // never scroll the scrollbars itself!
+ Window::Scroll(-nDeltaX, -nDeltaY,
+ PixelToLogic( Rectangle( Point(0, 0), aOutPixSz ) ) );
+ }
+ else
+ {
+ // repaint all
+ SetMapMode( aMap );
+ Invalidate();
+ }
+
+ Update();
+ }
+
+ if ( !bScrolling )
+ {
+ EndScroll( nDeltaX, nDeltaY );
+ if ( nDeltaX )
+ aHScroll.SetThumbPos( -aPixOffset.X() );
+ if ( nDeltaY )
+ aVScroll.SetThumbPos( -aPixOffset.Y() );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::ScrollLines( long nLinesX, long nLinesY )
+{
+ Size aDelta( PixelToLogic( Size( nColumnPixW, nLinePixH ) ) );
+ Scroll( aDelta.Width()*nLinesX, aDelta.Height()*nLinesY );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::ScrollPages( long nPagesX, ULONG nOverlapX,
+ long nPagesY, ULONG nOverlapY )
+{
+ Size aOutSz( GetVisibleArea().GetSize() );
+ Scroll( nPagesX * aOutSz.Width() + (nPagesX>0 ? 1 : -1) * nOverlapX,
+ nPagesY * aOutSz.Height() + (nPagesY>0 ? 1 : -1) * nOverlapY );
+}
+
+