source/ChooserSupportLDEF.c

/*
    ChooserSupport.c - C code for PACK and LDEF resources used by the Chooser.
    
    Copyright © 1992-1994 Apple Computer, Inc.
    All rights reserved.
 
    12/20/93        dmh             Sync'd with the shipping 1.0b3 GX driver.
     8/26/94        dmh             Sync'd with the shipping 1.0.1 GX driver.
     8/26/94        dmh             Universalized code.
*/
 
#include <Types.h>
#include <QuickDraw.h>
#include <Fonts.h>
#include <Lists.h>
#include <Devices.h>
#include <Resources.h>
#include <Script.h>
#include <ToolUtils.h>
#include <LowMem.h>
 
#ifndef __GXGRAPHICS__
    #include <GXGraphics.h>
#endif
#ifndef __GXPRINTERDRIVERS__
    #include <GXPrinterDrivers.h>
#endif
 
#include "ChooserSupportProtos.h"
 
 
// ------------------------------------------------------------------------
// INTERNAL DEFINES
// ------------------------------------------------------------------------
// Chooser initialize message selector
#define initializeMsg   11
 
// Icon Suite support
#define ttNone      0x0000
#define ttDisabled  0x0001
#define ttOffline   0x0002
#define ttOpen      0x0003
#define ttSelected  0x4000
#define ttSelectedDisabled  (ttSelected + ttDisabled)
#define ttSelectedOffline   (ttSelected + ttOffline)
#define ttSelectedOpen      (ttSelected + ttOpen)
 
#define ttLabel0    0x0000
#define ttLabel1    0x0100
#define ttLabel2    0x0200
#define ttLabel3    0x0300
#define ttLabel4    0x0400
#define ttLabel5    0x0500
#define ttLabel6    0x0600
#define ttLabel7    0x0700
 
// Copy of the DrawText trap
pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
    = 0xA885; 
 
 
// ------------------------------------------------------------------------
// ENTRY POINT FOR LDEF
// ------------------------------------------------------------------------
 
pascal void main(
    short       message,        // What operation to perform on list
    Boolean     select,         // Is this cell to be selected or not?
    Rect        *theRect,       // Rectangle of this cell, clipped to window
    Cell        theCell,        // Which cell this is
    short       dataOffset,     // Offset into data for this cell
    short       dataLen,        // Length of data for this cell
    ListHandle  theList)        // The list to act upon
/*
    An LDEF that works in two modes:
        - if the first two characters of the cell are valid AppleTalk NBP names (ie, not Å Å)
          then the LDEF is just a basic text LDEF
        - otherwise, it assumes the data is part of a PortListRec, which is
          a structure for icons with text underneath
*/
 
{
 
    gxPortListRec       theCellContents;
    Rect                iconRect;
    unsigned char       hiliteMode;
    
    switch (message)
        {
        case lDrawMsg:
        case lHiliteMsg:
        
            // save the data to avoid locking things down
            if (dataLen > sizeof(theCellContents) )
                dataLen = sizeof(theCellContents);
            BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
            
            // draw the cell as an icon, but only if we see our magic marker at the front
            if ( (theCellContents.firstMarker == 'Å') && (theCellContents.secondMarker == 'Å') )
                {
                // center the icon rect on the list with a top margin of 10 pixels
                iconRect.top = theRect->top + 10;
                iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
                iconRect.bottom = iconRect.top + 32;
                iconRect.right = iconRect.left + 32;
                
                
                // draw the icon
                if (theCellContents.iconSuiteHandle != nil)
                    PlotIconSuite(&iconRect,
                            ttNone, (select) ? ttSelected: ttNone,
                            theCellContents.iconSuiteHandle);
                            
                // Get the general area under the icon in which to draw the label
                iconRect.left = theRect->left + 2;
                iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
                iconRect.top = iconRect.bottom + 2;
                iconRect.bottom = theRect->bottom;
    
                // use a nice small font for the label          
                TextFont(applFont);
                TextSize(9);
                
                    {
                    short       labelWidth;
                    short       rectWidth;
                    short       labelHeight;
                    FontInfo    theInfo;
                
                    // Get rid of any text that was there before
                    EraseRect(&iconRect);
                    iconRect.top += 2;
                    
                    // compute the height of the label                  
                    GetFontInfo(&theInfo);
                    labelHeight = theInfo.ascent + theInfo.leading;
                    
                    // compute where to draw the text
                    iconRect.bottom = iconRect.top + labelHeight;
                    rectWidth = iconRect.right-iconRect.left;
                    
                    // truncate the string to fit within the box
                    TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
                    
                    // compute the new width of the string
                    labelWidth = StringWidth(theCellContents.iconName);
                    
                    // center the string, draw it
                    iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
                    MoveTo(iconRect.left, iconRect.bottom);
                    DrawString(theCellContents.iconName);
                    
                    if (select)
                        {
                        // compute right and lower edge of box bounding the text we just drew
                        iconRect.right = iconRect.left + labelWidth;
                        iconRect.bottom += theInfo.descent;
                        
                        // outset it, and invert it to select it
                        InsetRect(&iconRect, -1, -1);
                        hiliteMode = LMGetHiliteMode();
                        BitClr(&hiliteMode, pHiliteBit);
                        LMSetHiliteMode(hiliteMode);
                        InvertRect(&iconRect);
                        }
                    }
                    
                TextFont(applFont);
                TextSize(0);
                }
            else
                {
                // how boring!  It's only text
                FontInfo    theInfo;
                Rect        ourRect;
                short       cellWidth;
                
                // add a margin to the rectangle
                ourRect = *theRect;
                ourRect.left += 4;
                --ourRect.right;
                cellWidth = ourRect.right - ourRect.left;
                
                // erase the rectangle
                GetFontInfo(&theInfo);
                EraseRect(theRect);
                MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
                
                // hey, you can't park that string here -- it's too big!
                if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
                    {
                    // condense the text first
                    TextFace(condense);
                    
                    // then truncate afterwards
                    TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
                    }
                    
                // those darn other languages!
                if (GetSysJust() == teJustRight)
                    Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
                    
                OldDrawText((Ptr) &theCellContents, 0, dataLen);
                
                // if selected, invert it
                if (select)
                    {
                    hiliteMode = LMGetHiliteMode();
                    BitClr(&hiliteMode, pHiliteBit);
                    LMSetHiliteMode(hiliteMode);
                    InvertRect(theRect);
                    }
                    
                // normal text again
                TextFace(normal);
                }
                
            break;
            
        } // switch
        
} // LDEF