NotificationMon.ƒ/Source/NotificationWindow.c

#include "ScrollBar.h"
#include "NotificationMon.h"
#include "Event.h"
 
 NMRec          Notification;
 Boolean        NotificationPending = false;
 
void UpdateScrollMax(notificationDoc *nmd)
{
    short   pageSize;
    
    pageSize = RECT_HEIGHT((WINDOW(nmd).portRect)) / nmd->lineHt;
    if(nmd->ncount > pageSize)
        SetCtlMax(nmd->vScroll, nmd->ncount - pageSize);
    else
        SetCtlMax(nmd->vScroll, nmd->ncount);
}
 
 
void InitNotificationWindow(notificationDoc *nmd)
{
 
    nmd->vScroll =  NewVScrollBar(&nmd->nWin);
    GetWindowGlobalRect(&nmd->nWin.port, 
                    &nmd->nWin.port.portRect, 
                    &nmd->prefs.windowLoc);
 
    if(!RectInRgn(&nmd->prefs.windowLoc,GetGrayRgn()))
        MoveWindow(&nmd->nWin.port,4,40,false);
}
 
void SizeNotificationWindow(notificationDoc *nmd, EventRecord *evt)
{
    RgnHandle   desk;
    
    long    newSize;
    Rect    sizeRect;
    GrafPtr savePort;
    
    GetPort(&savePort);
    SetPort(&WINDOW(nmd));
 
    desk = GetGrayRgn();
    
    sizeRect.top = nmd->lineHt * 4;                     /* min height */
    sizeRect.bottom = sizeRect.top + nmd->lineHt * nmd->ncount;         /* max height */
 
    sizeRect.left = 128;                    /* min window width */
    sizeRect.right = sizeRect.left + (**desk).rgnBBox.right;
    
    newSize = GrowWindow(&WINDOW(nmd),evt->where,&sizeRect);
    SizeWindow(&WINDOW(nmd),LoWord(newSize),HiWord(newSize),false);
    SizeVScrollBar(nmd->vScroll, &WINDOW(nmd));
    UpdateScrollMax(nmd);
    InvalRect(&WINDOW(nmd).portRect);
    SetPort(savePort);
}
 
void ZoomNotificationWindow(notificationDoc *nmd, short part)
{
    WStateData  **wState;
    FontInfo    fi;
    GrafPtr     savePort;
    RgnHandle   desk;
    
    desk = GetGrayRgn();
    
    GetPort(&savePort);
    SetPort(&nmd->nWin);
    
    wState = nmd->nWin.dataHandle;
 
    (**wState).stdState.right = (**wState).stdState.left 
                    + nmd->longestLine;
 
    if(nmd->ncount > 3)
        (**wState).stdState.bottom = (**wState).stdState.top
                    + (nmd->lineHt * nmd->ncount);
    else
        (**wState).stdState.bottom = (**wState).stdState.top
                    + (nmd->lineHt * 4);
 
    if((**wState).stdState.bottom > (**desk).rgnBBox.bottom)
        (**wState).stdState.bottom = (**desk).rgnBBox.bottom; 
    
    
    if((**wState).stdState.right > (**desk).rgnBBox.right)
        (**wState).stdState.right = (**desk).rgnBBox.right;
    
    ZoomWindow(&nmd->nWin,part,true);
    UpdateScrollMax(nmd);
    SizeVScrollBar(nmd->vScroll, &nmd->nWin);
 
    SetPort(savePort);
}
 
void ActivateNotificationWindow(notificationDoc *nmd)
{
    ShowControl(nmd->vScroll);
}
 
 
void DeactivateNotificationWindow(notificationDoc *nmd)
{
    HideControl(nmd->vScroll);
}
 
 
void NotificationCheckScrollVis()
{
    if(InBackGround)
        HiliteControl(MainView->vScroll,255);
    else if( (MainView->ncount * MainView->lineHt) > RECT_HEIGHT(MainView->nWin.port.portRect) )
            HiliteControl(MainView->vScroll,0);
        else
            HiliteControl(MainView->vScroll,255);
}
 
void NotificationDocLayerSwitch()
{
 
    NotificationCheckScrollVis();
 
    if(!InBackGround && NotificationPending)
        NMRemove(&Notification);
 
    if(MainView->prefs.hideWindowInBackground)
        if(InBackGround)
            HideWindow(&MainView->nWin);
        else
            ShowWindow(&MainView->nWin);
}
 
void SelectNotification(WindowPtr wp, Point pt)
{
    Rect            hitRect;
    notificationDoc *nmd;   
    short           i;
    GrafPtr         savePort;
    Boolean         hitOne = false;
    long            postTick;
    
    GetPort(&savePort);
    SetPort(wp);
 
    nmd = (notificationDoc *)wp;
 
 
    hitRect = nmd->nWin.port.portRect;
    hitRect.right -= 16;
    hitRect.bottom = hitRect.top + nmd->lineHt;
    
    ClipRect(&hitRect);
    PenSize(4,4);
    MoveTo(pt.h,pt.v);
    LineTo(pt.h,pt.v);
    PenMode(patXor);
 
    for(i=1; i <= nmd->ncount; i++) {
        FrameRect(&hitRect);
        if(PtInRect(pt, &hitRect)) {
            hitOne = true;
            if( i == nmd->nSelection) {
                /* we bring the posting application forward */
            } else {
                InvalRect(&nmd->nWin.port.portRect);            /* update for new selection */
            /*
                if(nmd->nSelection) {
                    hitRect = nmd->nWin.port.portRect;
                    hitRect.right -= 16;
                    hitRect.bottom = hitRect.top + nmd->lineHt;
                    if(nmd->nSelection > 1)
                        OffsetRect(&hitRect,0,nmd->lineHt * nmd->nSelection);
                }
            */
                nmd->nSelection = i;
            }
        }
        FrameRect(&hitRect);
        Delay(30,&postTick);
        OffsetRect(&hitRect, 0, nmd->lineHt);
    }
    
    if(!hitOne && nmd->nSelection) {
        hitRect = nmd->nWin.port.portRect;
        hitRect.right -= 16;
        hitRect.bottom = hitRect.top + nmd->lineHt;
        if(nmd->nSelection > 1)
            OffsetRect(&hitRect,0,nmd->lineHt * nmd->nSelection);
        InvalRect(&hitRect);
        nmd->nSelection = 0;
    }
    
    PenNormal();
    SetPort(savePort);
}
 
void PostNotificationIcon()
{
 
    if(!MainView->prefs.notifyNewMessage) return;
    if(NotificationPending) return;
    
    Notification.qType = nmType;
    Notification.nmMark = 1;
    Notification.nmIcon = GetResource('SICN',128);
    Notification.nmSound = 0;
    Notification.nmStr = nil;
    Notification.nmResp = nil;
    Notification.nmRefCon = 'BRIG'; 
 
    NMInstall(&Notification);   
    NotificationPending = true;
}
 
pascal void NotificationScrollProc(ControlHandle ctl, short part)
{
    WindowPtr       wp;
    short           scrollAmt = 0, pageSize = 0, prevValue;
    RgnHandle       scrollRgn;
    Rect            scroll;
    
    pageSize = (RECT_HEIGHT(MainView->nWin.port.portRect) / MainView->lineHt) -1;
    
    switch(part) {
        case inUpButton:    scrollAmt = -1;
                            break;
        case inDownButton:  scrollAmt = 1;
                            break;
        case inPageUp:      scrollAmt = -pageSize;
                            break;
        case inPageDown:    scrollAmt = pageSize;
                            break;
    }
    
    if(scrollAmt) {
        prevValue = GetCtlValue(ctl);
        SetCtlValue(ctl, prevValue + scrollAmt);
        if(prevValue != GetCtlValue(ctl)) {
            scrollRgn = NewRgn();
            scroll = WINDOW(MainView).portRect;
            scroll.right -= 16;
            ScrollRect(&scroll, 0 , -(scrollAmt * MainView->lineHt), scrollRgn);
            InvalRgn(scrollRgn);
            BeginUpdate(&WINDOW(MainView));
            UpdateNotifications(MainView,GetCtlValue(ctl));
            EndUpdate(&WINDOW(MainView));
            DisposeRgn(scrollRgn);
        }
    }
}
 
void NotificationClick(WindowPtr wp, EventRecord *event)
{
        ControlHandle   whichControl;
        Point           pt;
        short           part;
        
        pt = event->where;
        GlobalToLocal(&pt);
        if(part = FindControl(pt,wp,&whichControl))
        {
            if(part == inThumb) {
                TrackControl(whichControl,pt,nil);
                UpdateNotifications(wp,GetCtlValue(whichControl));
            }
            else
                TrackControl(whichControl,pt,NotificationScrollProc);
        } else {
            SelectNotification(wp,pt);
        }
}