home *** CD-ROM | disk | FTP | other *** search
- // ObjectWindows - (C) Copyright 1992 by Borland International
-
- /* --------------------------------------------------------
- SCROLLER.CPP
- Defines type TScroller.
- -------------------------------------------------------- */
-
- #include "applicat.h"
- #include "window.h"
-
- #define max(a,b)(((a) >(b)) ?(a) :(b))
- #define min(a,b)(((a) <(b)) ?(a) :(b))
- #define abs(a) (((a) >= 0) ?(a) :-(a))
-
- hashValueType TScroller::ClassHashValue = 0;
-
- /* Constructs a TScroller object, initializing its data fields to
- default values. */
- TScroller::TScroller(PTWindow TheWindow,int TheXUnit, int TheYUnit, long TheXRange, long TheYRange)
- {
- Window = TheWindow;
- XPos = YPos = 0;
- XUnit = TheXUnit;
- YUnit = TheYUnit;
- XRange = TheXRange;
- YRange = TheYRange;
- XLine = 1; YLine = 1;
- XPage = 1; YPage = 1;
- AutoMode = TRUE;
- TrackMode = TRUE;
- AutoOrg = TRUE;
- HasHScrollBar = (Window &&
- ((Window->Attr.Style & WS_HSCROLL) == WS_HSCROLL));
- HasVScrollBar = (Window &&
- ((Window->Attr.Style & WS_VSCROLL) == WS_VSCROLL));
- InstanceHashValue = ClassHashValue++;
- }
-
- /* Destructs a TScroller object. Sets Window's Scroller member to NULL */
- TScroller::~TScroller()
- {
- if ( Window && Window->Scroller )
- Window->Scroller = NULL;
- }
-
- /* Sets the number of units per page (amount by which to scroll on
- a page scroll request) according to the current size of the
- Window's client area. */
- void TScroller::SetPageSize()
- {
- RECT ClientRect;
- int Width, Height;
-
- if ( Window )
- {
- GetClientRect(Window->HWindow, &ClientRect);
- Width = ClientRect.right - ClientRect.left;
- Height = ClientRect.bottom - ClientRect.top;
- if ( (Width != 0) && (XUnit > 0) )
- XPage = max(1, ((Width+1)/XUnit) -1);
- if ( (Height != 0) && (YUnit > 0) )
- YPage = max(1, ((Height+1)/YUnit) -1);
- }
- }
-
- /* Sets the range of the TScroller and also sets the range of
- its Window's scrollbars. */
- void TScroller::SetRange(long TheXRange, long TheYRange)
- {
- XRange = TheXRange;
- YRange = TheYRange;
- SetSBarRange();
- ScrollTo(XPos, YPos);
- }
-
- /* Resets the X and Y scroll unit size (in device units) to the passed
- parameters. Calls SetPageSize to update the X and Y page size, which
- are specified in scroll units. */
- void TScroller::SetUnits(int TheXUnit, int TheYUnit)
- {
- XUnit = TheXUnit;
- YUnit = TheYUnit;
- SetPageSize();
- }
-
- /* Sets the range of the Window's scrollbars. */
- void TScroller::SetSBarRange()
- {
- if ( Window )
- {
- if ( HasHScrollBar )
- SetScrollRange(Window->HWindow, SB_HORZ, 0,
- max(0, (int)min(XRange, MaxInt)), FALSE);
- if ( HasVScrollBar )
- SetScrollRange(Window->HWindow, SB_VERT, 0,
- max(0, (int)min(YRange, MaxInt)), FALSE);
- }
- }
-
- /* Sets the origin for the paint display context according to
- XPos, YPos. */
-
- inline void TScroller::__BeginView(HDC PaintDC, PAINTSTRUCT&)
- {
- long XOrg, YOrg;
-
- XOrg = XPos * XUnit;
- YOrg = YPos * YUnit;
- if ( AutoOrg && (XOrg <= MaxInt) && (YOrg <= MaxInt) )
- SetViewportOrg(PaintDC, (int)-XOrg, (int)-YOrg);
- }
-
- #if defined(WIN31)
- void TScroller::BeginView(HDC PaintDC, PAINTSTRUCT&)
- {
- PAINTSTRUCT ps_tmp;
- __BeginView(PaintDC, ps_tmp);
- }
- #endif
- #if defined(WIN30)
- void TScroller::BeginView(HDC_30 PaintDC, PAINTSTRUCT&)
- {
- PAINTSTRUCT ps_tmp;
- __BeginView( HDC( PaintDC ), ps_tmp);
- }
- #endif
-
- /* Updates the position of the Window's scrollbar(s). */
- void TScroller::EndView()
- {
- int TempPos;
-
- if ( Window )
- {
- if ( HasHScrollBar )
- {
- if ( XRange > MaxInt )
- TempPos = XScrollValue(XPos);
- else
- TempPos = (int)XPos;
- if ( GetScrollPos(Window->HWindow, SB_HORZ) != TempPos )
- SetScrollPos(Window->HWindow, SB_HORZ, TempPos, TRUE);
- }
- if ( HasVScrollBar )
- {
- if ( YRange > MaxInt )
- TempPos = YScrollValue(YPos);
- else
- TempPos = (int)YPos;
- if ( GetScrollPos(Window->HWindow, SB_VERT) != TempPos )
- SetScrollPos(Window->HWindow, SB_VERT, TempPos, TRUE);
- }
- }
- }
-
- /* Scrolls vertically according to scroll action and thumb position. */
- void TScroller::VScroll(WORD ScrollEvent, int ThumbPos)
- {
- switch (ScrollEvent) {
- case SB_LINEDOWN : ScrollBy(0, YLine);
- break;
- case SB_LINEUP : ScrollBy(0, -YLine);
- break;
- case SB_PAGEDOWN : ScrollBy(0, YPage);
- break;
- case SB_PAGEUP : ScrollBy(0, -YPage);
- break;
- case SB_TOP : ScrollTo(XPos, 0);
- break;
- case SB_BOTTOM : ScrollTo(XPos, YRange);
- break;
-
- case SB_THUMBPOSITION :
- if ( YRange > MaxInt )
- ScrollTo(XPos, YRangeValue(ThumbPos));
- else
- ScrollTo(XPos, ThumbPos);
- break;
- case SB_THUMBTRACK :
- if ( TrackMode )
- if ( YRange > MaxInt )
- ScrollTo(XPos, YRangeValue(ThumbPos));
- else
- ScrollTo(XPos, ThumbPos);
- if ( Window && HasVScrollBar )
- SetScrollPos(Window->HWindow, SB_VERT, ThumbPos, TRUE);
- break;
- } // switch
- }
-
- /* Scrolls horizontally according to scroll action and thumb
- position. */
- void TScroller::HScroll(WORD ScrollEvent, int ThumbPos)
- {
- switch (ScrollEvent) {
- case SB_LINEDOWN : ScrollBy(XLine, 0);
- break;
- case SB_LINEUP : ScrollBy(-XLine, 0);
- break;
- case SB_PAGEDOWN : ScrollBy(XPage, 0);
- break;
- case SB_PAGEUP : ScrollBy(-XPage, 0);
- break;
-
- case SB_TOP : ScrollTo(0, YPos);
- break;
- case SB_BOTTOM : ScrollTo(XRange, YPos);
- break;
-
- case SB_THUMBPOSITION :
- if ( XRange > MaxInt )
- ScrollTo(XRangeValue(ThumbPos), YPos);
- else
- ScrollTo(ThumbPos, YPos);
- break;
- case SB_THUMBTRACK :
- if ( TrackMode )
- if ( XRange > MaxInt )
- ScrollTo(XRangeValue(ThumbPos), YPos);
- else
- ScrollTo(ThumbPos, YPos);
- if ( (Window) && HasHScrollBar )
- SetScrollPos(Window->HWindow, SB_HORZ, ThumbPos, TRUE);
- break;
- } // switch
- }
-
- /* Scrolls to an (X,Y) position, after checking boundary conditions.
- Causes a WMPaint message to be sent. First scrolls the contents
- of the client area, if a portion of the client area will
- remain visible. */
- void TScroller::ScrollTo(long X, long Y)
- {
- long NewXPos , NewYPos;
-
- if ( Window )
- {
- NewXPos = max(0, min(X, XRange));
- NewYPos = max(0, min(Y, YRange));
- if ( (NewXPos != XPos) || (NewYPos != YPos) )
- {
- /* Scaling is not needed here. If condition is met, ScrollWindow()
- will succeed since XPage and YPage are ints. If condition is not
- met, ScrollWindow() is called in EndScroll() as a result of calling
- UpdateWindow(). EndScroll() performs the necessary scaling.
- */
- if ( AutoOrg || (abs(YPos - NewYPos) < YPage) &&
- (abs(XPos - NewXPos) < XPage) )
- ScrollWindow(Window->HWindow, (int)((XPos-NewXPos)*XUnit),
- (int)((YPos-NewYPos)*YUnit), NULL, NULL);
- else
- InvalidateRect(Window->HWindow, NULL, TRUE);
- XPos = NewXPos;
- YPos = NewYPos;
- UpdateWindow(Window->HWindow);
- }
- }
- }
-
- /* Performs "auto-scrolling". (Dragging the mouse from within the
- client area of the Window to without results in auto-scrolling
- when the AutoMode data member of the Scroller is TRUE). */
- void TScroller::AutoScroll()
- {
- POINT CursorPos;
- RECT ClientRect;
- long Dx , Dy;
-
- if ( AutoMode && Window )
- {
- GetCursorPos(&CursorPos);
- ScreenToClient(Window->HWindow, &CursorPos);
- GetClientRect(Window->HWindow, &ClientRect);
- Dx = 0; Dy = 0;
- if ( CursorPos.y < 0 )
- Dy = min(-YLine, max(-YPage, (CursorPos.y/10) * YLine));
- else
- if ( CursorPos.y > ClientRect.bottom )
- Dy = max(YLine, min(YPage,
- ((CursorPos.y - ClientRect.bottom)/10) * YLine));
- if ( CursorPos.x < 0 )
- Dx = min(-XLine, max(-XPage, (CursorPos.x/10) * XLine));
- else
- if ( CursorPos.x > ClientRect.right )
- Dx = max(XLine, min(XPage, ((CursorPos.x - ClientRect.right)/10) * XLine));
- ScrollBy(Dx, Dy);
- }
- }
-
- /* Reads an instance of TScroller from the passed ipstream. */
- void *TScroller::read(ipstream& is)
- {
- is >> XPos >> YPos
- >> XUnit >> YUnit
- >> XRange >> YRange
- >> XLine >> YLine
- >> XPage >> YPage
- >> AutoMode >> TrackMode
- >> AutoOrg
- >> HasHScrollBar >> HasVScrollBar;
- Window = NULL;
- InstanceHashValue = ClassHashValue++;
- return this;
- }
-
- /* Writes the TScroller to the passed opstream. */
- void TScroller::write(opstream& os)
- {
- os << XPos << YPos
- << XUnit << YUnit
- << XRange << YRange
- << XLine << YLine
- << XPage << YPage
- << AutoMode << TrackMode
- << AutoOrg
- << HasHScrollBar << HasVScrollBar;
- }
-
- TStreamable *TScroller::build()
- {
- return new TScroller(streamableInit);
- }
-
- TStreamableClass RegScroller("TScroller", TScroller::build,
- __DELTA(TScroller));
-