[comp.sys.mac.programmer] Follow Up On Centering DLOGs & ALRTs

engber@gumball.ils.nwu.edu (Mike Engber) (04/09/90)

Thanks for all the replys to my centering DLOG/ALRT question. I used the
best ideas to synthesize my solution which I think elegant enough to be
worth sharing. Attached are the relevant portions of my .h & .c files.

A couple of notes:

Several people`s solutions burned in the rsrc ids of the standard
file dialogs. You may want to note that there are named constants for
these values: putDlgID  & getDlgID.

All the solutions I was sent used screenBits.bounds. Is this what you
want in a multi-monitor situation? If not, what should you do?

Feel free to use/modify/comment-on this code, especially if you notice
any bugs or questionable practices.

-ME

---

/* DialogUtils.h */

/* Return topLeft point to center standard file dialogs. */
extern Point DU_StdPutWhere(void);
extern Point DU_StdGetWhere(void);

/*
 * Pre-load and center ALRT/DLOG template resources. Changes do not affect
 *  the resource file, but if the ALRT/DLOG is created soon after the call
 *  it will use the modified (centered) template in memory. Both routines
 *  return the passed rsrc id to allow calls like:
 *      Alert(DU_CenterALRT(alertID),filter);
 *      GetNewDialog(DU_CenterDLOG(dlogID),dStorage,behindWindow);
 */
extern short DU_CenterALRT(short rsrcId);
extern short DU_CenterDLOG(short rsrcId);


/* ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- */


/* DialogUtils.c */
 
#include "DialogUtils.h"

static void DU_CenterRect(Rect* rect_p){
/*
 * Alligns *rect_p wrt screenBits.bounds - LR centered & in upper 1/3
 */

    /* exactly centered */
    OffsetRect(rect_p,
            (screenBits.bounds.right + screenBits.bounds.left)/2 -
                (rect_p->right + rect_p->left)/2
        ,
            (screenBits.bounds.top + screenBits.bounds.bottom)/2 -
                (rect_p->top + rect_p->bottom)/2
        );
    
    /* up a bit */
    OffsetRect(rect_p,0, 
        GetMBarHeight() - 2*(rect_p->top - screenBits.bounds.top)/3);
}

static Point DU_Where(short rsrcId){
/*
 * Returns centering point for the topLeft corner of a dialog.
 */
    Handle  h = GetResource('DLOG',rsrcId);
    Rect    r = {0,0,0,0};
    if(h){
        r = *((Rect*)(*h));
        DU_CenterRect(&r);
        ReleaseResource(h);
    }
    return topLeft(r);
}

Point DU_StdPutWhere(void){
    return DU_Where(putDlgID);
}

Point DU_StdGetWhere(void){
    return DU_Where(getDlgID);
}

static short DU_Center(ResType type, short rsrcId){
/*
 * Reads in an 'ALRT' or 'DLOG' rsrc template & centers it's display Rect.
 */
    Handle  h = GetResource(type,rsrcId);
    if(h) DU_CenterRect((Rect*)(*h));
    return rsrcId;
}

short DU_CenterALRT(short rsrcId){
    return DU_Center('ALRT',rsrcId);
}

short DU_CenterDLOG(short rsrcId){
    return DU_Center('DLOG',rsrcId);
}

kazim@Apple.COM (Alex Kazim) (04/13/90)

In article <6178@accuvax.nwu.edu> engber@gumball (Mike Engber) writes:
>
>All the solutions I was sent used screenBits.bounds. Is this what you
>want in a multi-monitor situation? If not, what should you do?
>

The location of the dialog should be tied to the area of user 
attention.  For instance, if the alert is an out-of-range alert for
a field in a window, the alert should appear on the same screen as the
"owning" window.

You can do this by walking the GDevice list, determining which screen the
"owning" window is "most" on (SectRect the gDeviceRect with portRect),
and placing the alert on that screen.

Also, I think you should center the alerts using a 1/3 to 2/3, top-to-
bottom ratio.  In English, the space under the dialog is TWICE the
space above the dialog.

====================================================================
Alex Kazim, Apple Computer
No, but I do get paid for my opinions
====================================================================