home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************************
- *
- *
- * ObjectMacZapp -- a standard Mac OOP application template
- *
- *
- *
- * ZScroller.cpp -- a window with scrollbars
- *
- *
- *
- *
- *
- * © 1996, Graham Cox
- *
- *
- *
- *
- *************************************************************************************************/
-
-
- #include "ZScroller.h"
- #include "ZErrors.h"
-
-
- static pascal void ScrollBarZProc(ControlHandle theControl, short partCode);
- static pascal void ThumbZProc();
-
- static ControlActionUPP gScrollbarProc = NewControlActionProc(ScrollBarZProc);
- static ControlHandle gCurrentScrollbar = NULL;
-
- /*--------------------------------*** CONSTRUCTOR ***---------------------------------*/
-
- ZScroller::ZScroller(ZCommander* aBoss, short windID, Boolean hasHScroll, Boolean hasVScroll)
- : ZWindow(aBoss, windID)
- {
- theHBar = NULL;
- theVBar = NULL;
- SetRect(&scrollBounds,0,0,0,0);
- hScale = 1;
- vScale = 1;
-
- hasHBar = hasHScroll;
- hasVBar = hasVScroll;
- }
-
-
- /*--------------------------------*** INITZWINDOW ***---------------------------------*/
- /*
-
- overrides the base ZWindow to initialise the scrollbars as well
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::InitZWindow()
- {
- inherited::InitZWindow(); // do the basic initialisation
-
- MakeScrollbars(); // make the scrollbar controls
- }
-
-
-
- /*----------------------------------*** ACTIVATE ***----------------------------------*/
- /*
-
- overrides ZWindow to show the scrollbars when the window state changes
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::Activate()
- {
- if (hasVBar)
- ShowControl(theVBar);
-
- if (hasHBar)
- ShowControl(theHBar);
-
- inherited::Activate();
- }
-
-
- /*---------------------------------*** DEACTIVATE ***---------------------------------*/
- /*
-
- overrides ZWindow to hide the scrollbars when the window state changes
-
- ----------------------------------------------------------------------------------------*/
-
-
- void ZScroller::Deactivate()
- {
- if (hasVBar)
- HideControl(theVBar);
-
- if (hasHBar)
- HideControl(theHBar);
-
- inherited::Deactivate();
- }
-
-
-
- /*------------------------------------*** DRAW ***------------------------------------*/
- /*
-
- overrides ZWindow to draw the content allowing for the scroll and the scrollbars themselves
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::Draw()
- {
- // need to set the origin to the scroll position here
-
- Rect content;
- short fH, fV;
-
- GetContentRect(&content);
- SetOriginToScroll();
-
- GetPosition(&fH, &fV);
- OffsetRect(&content, fH, fV);
- ClipRect(&content);
-
- DrawContent();
-
- SetOrigin(0,0);
- ClipRect(&macWindow->portRect);
- DrawControls(macWindow);
- DrawGrow();
- }
-
-
- /*----------------------------------*** DRAWGROW ***----------------------------------*/
- /*
-
- overrides ZWindow to draw the grow box, allowing for the actual scrollbars present
-
- ----------------------------------------------------------------------------------------*/
-
-
- void ZScroller::DrawGrow()
- {
- // overrides the standard method to clip down to the growbox. This prevents
- // scrollbar lines being drawn when there are no scrollbars in one dimension
-
- Rect growBoxRect = macWindow->portRect;
-
- if (! hasVBar)
- growBoxRect.top = growBoxRect.bottom - kStdScrollbarWidth;
-
- if (! hasHBar)
- growBoxRect.left = growBoxRect.right - kStdScrollbarWidth;
-
- ClipRect(&growBoxRect);
- DrawGrowIcon(macWindow);
- ClipRect(&macWindow->portRect);
- }
-
-
-
- /*------------------------------------*** CLICK ***-----------------------------------*/
- /*
-
- overrides ZWindow to handle clicks in the scrollbars and perform the scrolling
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::Click(Point mouse, short modifiers)
- {
- // handle a click in the content and also the scrollbar clicks
-
- short partCode,curValue;
- ControlHandle hitCtl;
-
- partCode = FindControl(mouse, macWindow, &hitCtl);
-
- if (theVBar, vPosition);
-
- Draw();
- }
-
-
-
- /*-------------------------------*** GETCONTENTRECT ***-------------------------------*/
- /*
-
- get the scrollable portion of the window- the bit you can see, less the scrollbars.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::GetContentRect(Rect* aRect)
- {
- // returns the scrollable part of the window. The bit without the scrollbars.
-
- *aRect = macWindow->portRect;
- if (hasVBar)
- aRect->right -= kStdScrollbarWidth;
-
- if (hasHBar)
- aRect->bottom -= kStdScrollbarWidth;
- }
-
-
-
- /*---------------------------*** CALCULATECONTROLPARAMS ***---------------------------*/
- /*
-
- sets the scrollbar maximums to correctly scroll the scrollarea. This is called when the
- scrollbounds or the window frame area changes.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::CalculateControlParams()
- {
- // this sets the maximums of the scrollbar to the difference between the content rect and
- // the scrollbounds.
-
- Rect content;
- short hMax,vMax;
-
- GetContentRect(&content);
-
- hMax = scrollBounds.right - scrollBounds.left - content.right - content.left;
- vMax = scrollBounds.bottom - scrollBounds.top - content.bottom - content.top;
-
- if (hMax < 0)
- hMax = 0;
-
- if (vMax < 0)
- vMax = 0;
-
- if (hasHBar)
- SetControlMaximum(theHBar, hMax);
-
- if (hasVBar)
- SetControlMaximum(theVBar, vMax);
- }
-
-
-
- /*-------------------------------*** MAKESCROLLBARS ***-------------------------------*/
- /*
-
- creates the scrollbars as part of the initialisation
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::MakeScrollbars()
- {
- // create the scrollbar controls initially. This is done by calling NewControl. We
- // figure out the control rects from the window portrect.
-
- Rect barRect;
- Rect wPortRect;
-
- wPortRect = macWindow->portRect;
-
- if (hasHBar)
- {
- barRect = wPortRect;
- barRect.right -= kStdScrollbarWidth - 1;
- barRect.top = barRect.bottom - kStdScrollbarWidth - 1;
- barRect.left -= 1;
- OffsetRect(&barRect,0,1);
-
- FailNIL(theHBar = NewControl(macWindow, &barRect, NULL, FALSE, 0, 0, 0, scrollBarProc, (long) this));
- }
-
- if (hasVBar)
- {
- barRect = wPortRect;
- barRect.bottom -= kStdScrollbarWidth - 1;
- barRect.left = barRect.right - kStdScrollbarWidth - 1;
- barRect.top -= 1;
- OffsetRect(&barRect,1,0);
-
- FailNIL(theVBar = NewControl(macWindow, &barRect, NULL, FALSE, 0, 0, 0, scrollBarProc, (long) this));
- }
- }
-
-
-
- /*-------------------------------*** MOVESCROLLBARS ***-------------------------------*/
- /*
-
- moves the scrollbars to the edges of the window. Called when the window frame size changes.
- The scrollbars should generally be hidden before this operation. This then reshows them if
- the window is active, and recomputes the max values. If the scroll position is forced to
- change as a result, this redraws the content in the correct position.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::MoveScrollbars()
- {
- // move the scrollbars after the window size has changed. They should be hidden beforehand
- // and then shown afterwards. This will only show them if the window is active.
-
- Rect wPortRect;
- short w,h,hVal = 0,vVal = 0;
- Boolean isActive;
-
- wPortRect = macWindow->portRect;
- isActive = IsWindowHilited(macWindow); // using Copland type macro
-
- if (hasHBar)
- {
- hVal = GetControlValue(theHBar);
-
- w = wPortRect.right - wPortRect.left - kStdScrollbarWidth + 2;
- h = kStdScrollbarWidth + 1;
-
- SizeControl(theHBar, w, h );
- MoveControl(theHBar, wPortRect.left - 1, wPortRect.bottom - kStdScrollbarWidth);
-
- if (isActive)
- ShowControl(theHBar);
-
- ValidRect(&(*theHBar)->contrlRect);
- }
-
- if (hasVBar)
- {
- vVal = GetControlValue(theVBar);
-
- h = wPortRect.bottom - wPortRect.top - kStdScrollbarWidth + 2;
- w = kStdScrollbarWidth + 1;
-
- SizeControl(theVBar, w, h );
- MoveControl(theVBar, wPortRect.right - kStdScrollbarWidth, wPortRect.top - 1 );
-
- if (isActive)
- ShowControl(theVBar);
-
- ValidRect(&(*theVBar)->contrlRect);
- }
-
- CalculateControlParams(); // recompute maximums
-
- if (hasVBar)
- vVal -= GetControlValue(theVBar);
-
- if (hasHBar)
- hVal -= GetControlValue(theHBar);
-
- // if the value of the control changed as a result of altering the maximum, we need to
- // ensure that the contents are scrolled to the right place.
-
- if (hVal || vVal)
- {
- GetContentRect(&wPortRect);
- EraseRect(&wPortRect);
- }
- }
-
-
-
- /*---------------------------------*** POSTSCROLL ***---------------------------------*/
- /*
-
- You can override this if you are interested in getting called after the thumb of a
- scrollbar was dragged.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::PostScroll()
- {
- }
-
-
- /*------------------------------------*** SCROLL ***----------------------------------*/
- /*
-
- shifts the content by dH and dV, updating the revealed area. This is called by the scroll
- bar callback function to implement continous scrolling.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::Scroll(short dH, short dV)
- {
- // scrolls the content rect. This calls scrollrect to move the majority of the
- // pixels, then calls DrawContent to fill in the rest.
-
- RgnHandle updateRgn,saveClip;
- Rect content;
- short fH,fV;
-
- GetContentRect(&content);
- updateRgn = NewRgn();
-
- GetClip(saveClip = NewRgn());
- ScrollRect(&content, dH, dV, updateRgn);
-
- // need to set the origin of the view to the new location
-
- SetOriginToScroll();
-
- // offset the update region to allow for the origin
-
- GetPosition(&fH, &fV);
- OffsetRgn(updateRgn, fH, fV);
- SetClip(updateRgn);
-
- // draw the update region
-
- DrawContent();
-
- // restore the zero origin
-
- SetOrigin(0,0);
- SetClip(saveClip);
-
- DisposeRgn(saveClip);
- DisposeRgn(updateRgn);
- }
-
-
- /*-----------------------------*** SETORIGINTOSCROLL ***------------------------------*/
- /*
-
- sets the origin of the grafport to the correct scroll position. This is done to ensure
- that the contents get drawn in the right place regardless of where they are scrolled to.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::SetOriginToScroll()
- {
- short vOrigin = 0;
- short hOrigin = 0;
-
- if (hasVBar)
- vOrigin = GetControlValue(theVBar);
-
- if (hasHBar)
- hOrigin = GetControlValue(theHBar);
-
- SetOrigin(hOrigin, vOrigin);
- }
-
-
- /*-------------------------------*** SCROLLHANDLER ***--------------------------------*/
- /*
-
- scrollbar callback function actually changes the scrollbar value as scrolling progresses
- and scrolls the content accordingly.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZScroller::ScrollHandler(ControlHandle aCtl, short partCode)
- {
- // this actually peforms the scroll of the content rect
-
- short curValue,page;
- Boolean hitIsVertical;
- Rect content;
-
- curValue = GetControlValue(aCtl);
-
- // are we scrolling the horizontal or the vertical bar? Find out by comparing
- // the control with one of our data members
-
- hitIsVertical = (aCtl == theVBar);
-
- // calculate the page amount. This is the height or width of the window less one
- // scale amount.
-
- GetContentRect(&content);
-
- if (hitIsVertical)
- page = content.bottom - content.top - vScale;
- else
- page = content.right - content.left - hScale;
-
- switch (partCode)
- {
- case kControlUpButtonPart:
- SetControlValue(aCtl, GetControlValue(aCtl) - (hitIsVertical? vScale : hScale));
- break;
- case kControlDownButtonPart:
- SetControlValue(aCtl, GetControlValue(aCtl) + (hitIsVertical? vScale : hScale));
- break;
- case kControlPageUpPart:
- SetControlValue(aCtl, GetControlValue(aCtl) - page);
- break;
- case kControlPageDownPart:
- SetControlValue(aCtl, GetControlValue(aCtl) + page);
- break;
- }
-
- curValue -= GetControlValue(aCtl);
-
- if (hitIsVertical)
- Scroll(0, curValue);
- else
- Scroll(curValue, 0);
- }
-
-
-
-
-
-
-
-
- static pascal void ScrollBarZProc(ControlHandle theControl, short partCode)
- {
- // action proc for passing scrolling callbacks back to the object.
-
- ZScroller* aScroller = (ZScroller*) GetCRefCon(theControl);
-
- if (aScroller)
- aScroller->ScrollHandler(theControl, partCode);
- }
-
-
-
- static pascal void ThumbZProc()
- {
-
-
-
-
- }
-
-