Source/scrolls.c

/*************************************************************************************
#
#       scrolls.c
#
#       This segment handles the scroll bars.
#
#       Author(s):  Michael Marinkovich & Guillermo Ortiz
#                   marink@apple.com
#
#       Modification History: 
#
#           4/3/96      MWM     Initial coding                   
#
#       Copyright © 1992-96 Apple Computer, Inc., All Rights Reserved
#
#
#       You may incorporate this sample code into your applications without
#       restriction, though the sample code has been provided "AS IS" and the
#       responsibility for its operation is 100% yours.  However, what you are
#       not permitted to do is to redistribute the source as "DSC Sample Code"
#       after having made changes. If you're going to re-distribute the source,
#       we require that you make it clear in the source that the code was
#       descended from Apple Sample Code, but that you've made changes.
#
*************************************************************************************/
 
#include <Events.h>
#include <ToolUtils.h>
#include <Gestalt.h>
#include <OSUtils.h>
 
 
#include "App.h"
#include "Proto.h"
 
 
//----------------------------------------------------------------------
//
//  Globals - 
//
//----------------------------------------------------------------------
 
extern Boolean      gInBackground;
 
 
//----------------------------------------------------------------------
//
//  InstallScrollBars -
//               
//
//----------------------------------------------------------------------
 
void InstallScrollBars(WindowRef window, DocHnd doc)
{
    Rect        bounds;
    
    
    // calc horiz scroll bar
    bounds = window->portRect;
    
    bounds.right++;
    bounds.left = bounds.right - (kScrollWidth + 1);
    bounds.top--;
    bounds.bottom -= (kScrollWidth - 1);
    
    (**doc).hScroll = NewControl(window, &bounds, nil, true,
                                  0, 0, 0, scrollBarProc, nil);
                                  
    // calc vert scroll bar
    bounds = window->portRect;
 
    bounds.left--;
    bounds.right -= (kScrollWidth - 1);
    bounds.top = bounds.bottom - kScrollWidth;
    bounds.bottom++;
    
 
    (**doc).vScroll = NewControl(window, &bounds, nil, true,
                                  0, 0, 0, scrollBarProc, nil);
 
                                  
}
 
 
//----------------------------------------------------------------------
//
//  AdjustScrollValues -
//               
//
//----------------------------------------------------------------------
 
void AdjustScrollValues(WindowRef window)
{
    Rect                    contRect;
    Rect                    picFrame;
    ControlHandle           hCntrl;
    ControlHandle           vCntrl;
    short                   oldValue;
    short                   lines;
    short                   max;
    DocHnd                  doc;
    
    doc = (DocHnd)GetWRefCon(window);
    
    if (doc != nil) {
        hCntrl = (**doc).hScroll;
        vCntrl = (**doc).vScroll;
 
        GetContRect(window,&contRect);
        
        if ((**doc).pict != nil || (**doc).world != nil)
            picFrame = (**doc).world->portRect;
        else
            SetRect(&picFrame, 0, 0, 0, 0);
            
        oldValue = GetCtlValue(vCntrl);
        lines = picFrame.bottom - picFrame.top;
        max = lines - contRect.bottom ;
        if ( max < 0 ) max = 0;
        SetCtlMax(vCntrl, max);
    
        if(oldValue + contRect.bottom > lines)
            SetCtlValue(vCntrl, max);
        
        oldValue = GetCtlValue(hCntrl);
        lines = picFrame.right - picFrame.left;
        max = lines - contRect.right;
        if ( max < 0 ) max = 0;
        SetCtlMax(hCntrl, max);
    
        if(oldValue + contRect.right > lines)
            SetCtlValue(hCntrl, max);
                
    }       
            
}
 
 
//----------------------------------------------------------------------
//
//  AdjustScrollbars -
//               
//
//----------------------------------------------------------------------
 
void AdjustScrollbars(WindowRef window, Boolean resize)
{
    ControlRef      hCtl;
    ControlRef      vCtl;
    Rect            r;
    DocHnd          doc;
 
    
    doc = (DocHnd)GetWRefCon(window);
    
    if (doc != nil && resize) {
        hCtl = (**doc).hScroll;
        vCtl = (**doc).vScroll;
        GetContRect(window, &r);
        
        // resize horizontal
        MoveControl(hCtl, -1, r.bottom);
        SizeControl(hCtl, (r.right - r.left) + 2, kScrollWidth + 1);
        
        // resize vertical
        MoveControl(vCtl, r.right, -1);
        SizeControl(vCtl, kScrollWidth + 1, r.bottom + 2);
    }
    
    // adjust scrollbar values to match
    AdjustScrollValues(window);
}
 
 
//----------------------------------------------------------------------
//
//  ScrollActionProc -
//               
//
//----------------------------------------------------------------------
 
pascal void ScrollActionProc(ControlRef control, short part)
{
    WindowRef       window;
    short           amount;
    short           value;
    short           max;
    short           hAmount;
    short           vAmount;
    DocHnd          doc;
    
    window = (**control).contrlOwner;
    doc = (DocHnd)GetWRefCon(window);
    
    if (doc != nil) {
        if ( part != 0 ) {              
            window = (*control)->contrlOwner;
            hAmount = vAmount = 0;
            
            value = GetCtlValue(control);   
            max = GetCtlMax(control);       
        
            switch ( part ) {
                case inUpButton:
                case inDownButton:      // one line
                        amount = 8;
                        break;
                        
                case inPageUp:          // one page
                case inPageDown:
                        amount = 64;
                        break;
            }
            
            if ( (part == inDownButton) || (part == inPageDown) )
                amount = -amount;       // reverse direction for a downer
            
            amount = value - amount;
            if ( amount < 0 )
                amount = 0;
            else if ( amount > max )
                amount = max; 
            SetCtlValue(control, amount);
            
            amount = value - amount;        // calculate the real change
            
            if ( amount != 0 ) {
                if (control == (**doc).hScroll)
                    hAmount = amount;
                else
                    vAmount = amount ;
                        
                MyScrollPicture(window,hAmount, vAmount);
            }
        }   
    }   
}
    
 
//----------------------------------------------------------------------
//
//  MyScrollPicture -
//               
//
//----------------------------------------------------------------------
 
void MyScrollPicture(WindowRef window, short hs, short vs)
{
    RgnHandle       updateRgn;
    GWorldPtr       oldWorld;
    GWorldPtr       theWorld;
    GDHandle        oldGD;
    PixMapHandle    thePix;
    Rect            contRect;
    Rect            pictRect;
    DocHnd          doc;
    
    doc = (DocHnd)GetWRefCon(window);
    
    if (doc != nil) {
        GetGWorld(&oldWorld, &oldGD);
        SetPort(window);
        
        GetContRect(window, &contRect);
        ScrollRect(&contRect, hs, vs, updateRgn = NewRgn());
        
        theWorld = (**doc).world;
        pictRect = theWorld->portRect;
        
        thePix = GetGWorldPixMap(theWorld);
        if (LockPixels(thePix)) {
            SetGWorld((CGrafPtr)window, nil);
            OffsetRect(&pictRect, -GetCtlValue((**doc).hScroll), 
                      -GetCtlValue((**doc).vScroll));
 
            CopyBits((BitMap *) *thePix, &window->portBits,
                    &theWorld->portRect, &pictRect, srcCopy,updateRgn);
            
            UnlockPixels(thePix);
            
            SetGWorld(oldWorld, oldGD);
        }           
        ClipRect(&window->portRect);
        DisposeRgn(updateRgn);
    }
        
}   
 
 
//----------------------------------------------------------------------
//
//  GetContRect -
//               
//
//----------------------------------------------------------------------
 
void GetContRect(WindowRef window,Rect *contRect)
{
    *contRect = window->portRect;   // get the content rect for our window
    
    contRect->right -= 15;          // subtract the scroll bars from the rect
    contRect->bottom -= 15;
 
 
}