appletpopup.c

Go to the documentation of this file.
00001 
00002 /*  $Id: appletpopup.c 355 2005-01-11 22:48:55Z andreradke $    */
00003 
00004 /* copyright 1991-96 UserLand Software, Inc. All Rights Reserved.*/
00005 
00006 
00007 #include "appletmemory.h"
00008 #include "appletstrings.h"
00009 #include "appletfont.h"
00010 #include "appletmouse.h"
00011 #include "appletquickdraw.h"
00012 #include "appletops.h"
00013 #include "appletcursor.h"
00014 #include "appletmenuops.h"
00015 #include "appletpopup.h"
00016 
00017 
00018 #define defaultpopupfontnum geneva
00019 #define defaultpopupfontsize 9
00020 #define defaultpopupfontstyle 0
00021 
00022     
00023 static short trackericonnum;
00024 
00025 static Rect trackerrect;
00026 
00027 
00028 
00029 boolean initpopuprecord (typopuprecord *popup) {
00030     
00031     /*
00032     11/11/92 DW: call this when you're initializing a popup record. it doesn't
00033     allocate anything, it just sets up the record so that default values are in
00034     place. this may be important as the applet toolkit popup support evolves.
00035     */
00036     
00037     clearbytes (popup, longsizeof (typopuprecord));
00038     
00039     (*popup).fontnum = defaultpopupfontnum;
00040         
00041     (*popup).fontsize = defaultpopupfontsize;
00042         
00043     (*popup).fontstyle = defaultpopupfontstyle;
00044         
00045     return (true);
00046     } /*initpopuprecord*/
00047     
00048 
00049 boolean pushpopupitem (typopuprecord *popup, bigstring bs, boolean flenabled) {
00050     
00051     MenuHandle hmenu = (*popup).hmenu;
00052     bigstring bsspace;
00053     
00054     if (equalstrings (bs, "\p(-")) /*take disabled seperator as is*/
00055         AppendMenu (hmenu, bs);
00056     
00057     else { /*to allow meta-characters in bs, append blank item, then set item text*/
00058         
00059         setstringwithchar (chspace, bsspace);
00060         
00061         AppendMenu (hmenu, bsspace);
00062         
00063         if (!isemptystring (bs))
00064             SetItem (hmenu, CountMItems (hmenu), bs);
00065         }
00066     
00067     if (!flenabled)
00068         DisableItem (hmenu, CountMItems (hmenu));
00069 
00070     return (true);
00071     } /*pushpopupitem*/
00072     
00073     
00074 static void displaypopupicon (Rect r, boolean flenabled) {
00075     
00076     short iconnum;
00077     
00078     if (flenabled)
00079         iconnum = 0;
00080     else
00081         iconnum = 1;
00082     
00083     #ifdef clayBasket /*6/24/93 DW: conflict between SICN resources*/
00084         
00085         plotsmallicon (r, 133, iconnum, false);
00086         
00087     #else
00088     
00089         plotsmallicon (r, 129, iconnum, false);
00090     
00091     #endif
00092     } /*displaypopupicon*/
00093     
00094     
00095 void idealpopupsize (typopuprecord *popup, short *height, short *width) {
00096     
00097     /*
00098     11/11/92 DW: based on the string and font/size/style and other attributes
00099     of the popup record, determine the ideal height and width for the rect used
00100     to display the popup. this is needed by IOWA in it's Clean Object command.
00101     */
00102     
00103     short h, w;
00104     short maxwidth;
00105     
00106     pushstyle ((*popup).fontnum, (*popup).fontsize, (*popup).fontstyle);
00107     
00108     h = globalfontinfo.ascent + globalfontinfo.descent + 4;
00109     
00110     maxwidth = StringWidth ((*popup).bs);
00111     
00112     (*popup).fldisposemenu = true; /*assume the menu was created dynamically, not loaded from resource*/
00113     
00114     if ((*popup).getmenucallback ()) { /*use the strings in the menu to determine width*/
00115         
00116         MenuHandle hmenu = (*popup).hmenu;
00117         short i;
00118         short sw;
00119         short lastitem;
00120         bigstring bs;
00121         
00122         lastitem = countmenuitems (hmenu);
00123         
00124         for (i = 1; i <= lastitem; i++) {
00125             
00126             getmenuitem (hmenu, i, bs);
00127             
00128             sw = StringWidth (bs);
00129             
00130             if (sw > maxwidth)
00131                 maxwidth = sw;
00132             } /*for*/
00133         
00134         if ((*popup).fldisposemenu)
00135             DisposeMenu (hmenu);
00136         }
00137         
00138     w = maxwidth + popuparrowwidth + popupdrawinset + 8;
00139     
00140     popstyle ();
00141     
00142     *height = h;
00143     
00144     *width = w;
00145     } /*idealpopupsize*/
00146     
00147     
00148 void drawpopup (typopuprecord *popup) {
00149     
00150     Rect rpopup = (*popup).popuprect;
00151     bigstring bs;
00152     Rect r;
00153     
00154     if (emptyrect (rpopup))
00155         return;
00156     
00157     pushbackcolor (&whitecolor);
00158     
00159     r = rpopup;
00160     
00161     EraseRect (&r);
00162     
00163     InsetRect (&r, 1, 1);
00164     
00165     r.left = r.right - popuparrowwidth;
00166     
00167     displaypopupicon (r, true);
00168     
00169     r = rpopup;
00170     
00171     FrameRect (&r);
00172     
00173     MoveTo (r.left + 1, r.bottom);
00174     
00175     LineTo (r.right, r.bottom);
00176     
00177     LineTo (r.right, r.top + 1);
00178     
00179     r.right -= popuparrowwidth;
00180     
00181     InsetRect (&r, 4, 2);
00182 
00183     pushstyle ((*popup).fontnum, (*popup).fontsize, (*popup).fontstyle);
00184     
00185     if ((*popup).drawcontentscallback != nil) /*DW 7/2/93*/
00186         (*popup).drawcontentscallback (r);
00187     else {
00188     
00189         MoveTo (r.left, r.bottom - globalfontinfo.descent - 1);
00190     
00191         copystring ((*popup).bs, bs);
00192     
00193         ellipsize (bs, r.right - r.left);
00194     
00195         DrawString (bs);
00196         }
00197     
00198     popstyle ();
00199     
00200     zerorect (&(*popup).leftarrowrect);
00201     
00202     if ((*popup).flarrows || (*popup).flleftarrow) {
00203     
00204         r = rpopup;
00205         
00206         r.right = r.left - popupdrawinset;
00207         
00208         r.left = r.right - widthsmallicon;
00209         
00210         OffsetRect (&r, 2, 1); /*move it right by two pixels, down by one pixel*/
00211         
00212         (*popup).leftarrowrect = r;
00213         
00214         plotsmallicon (r, 128, 1, false); 
00215         }
00216     
00217     zerorect (&(*popup).rightarrowrect);
00218     
00219     if ((*popup).flarrows || (*popup).flrightarrow) {
00220     
00221         r = rpopup;
00222         
00223         r.left = r.right + popupdrawinset;
00224         
00225         r.right = r.left + widthsmallicon;
00226         
00227         OffsetRect (&r, -2, 1); /*move it left by two pixels, down by one pixel*/
00228         
00229         (*popup).rightarrowrect = r;
00230         
00231         plotsmallicon (r, 128, 0, false); 
00232         }
00233     
00234     popbackcolor ();
00235     } /*drawpopup*/
00236     
00237 
00238 static void icontracker (boolean flpressed) {
00239     
00240     /*
00241     callback routine for the mouse tracker.
00242     */
00243     
00244     short iconnum = trackericonnum;
00245     
00246     if (flpressed)
00247         iconnum += 2;
00248         
00249     pushbackcolor (&lightbluecolor);
00250     
00251     EraseRect (&trackerrect);
00252     
00253     plotsmallicon (trackerrect, 128, iconnum, false);
00254     
00255     popbackcolor ();
00256     } /*icontracker*/
00257     
00258     
00259 static boolean arrowtracker (Rect r, popupcallback arrowcallback) {
00260 
00261     trackerrect = r;
00262     
00263     icontracker (true); /*display button in its pressed state*/
00264     
00265     if (mousetrack (r, &icontracker)) {
00266     
00267         icontracker (false); /*display button in its un-pressed state*/
00268     
00269         (*arrowcallback) ();
00270         }
00271     
00272     return (true);
00273     } /*arrowtracker*/
00274 
00275 
00276 boolean popupclick (typopuprecord *popup) {
00277     
00278     /*
00279     10/22/92 DW: added fldisposemenu field to a popup record. if the menu comes from
00280     the resource fork of the application, set this to false. if it gets disposed, the
00281     resource manager will crash. needed in the calendar program.
00282     */
00283 
00284     if (PtInRect (mousestatus.localpt, &(*popup).leftarrowrect)) {
00285         
00286         trackericonnum = 1;
00287         
00288         if ((*popup).trackleftarrow) /*the caller handles tracking*/
00289             (*(*popup).leftarrowcallback) ();
00290         else
00291             arrowtracker ((*popup).leftarrowrect, (*popup).leftarrowcallback);
00292         
00293         return (true);
00294         }
00295 
00296     if (PtInRect (mousestatus.localpt, &(*popup).rightarrowrect)) {
00297         
00298         trackericonnum = 0;
00299     
00300         if ((*popup).trackrightarrow) /*the caller handles tracking*/
00301             (*(*popup).rightarrowcallback) ();
00302         else
00303             arrowtracker ((*popup).rightarrowrect, (*popup).rightarrowcallback);
00304         
00305         return (true);
00306         }
00307         
00308     if (PtInRect (mousestatus.localpt, &(*popup).popuprect)) {
00309         
00310         MenuHandle hmenu;
00311         Point pt;
00312         boolean flcommandselected = false;
00313         
00314         (*popup).fldisposemenu = true; /*assume the menu was created dynamically, not loaded from resource*/
00315         
00316         if (!(*popup).getmenucallback ()) /*error, but consume the mouse click*/
00317             return (true);
00318         
00319         hmenu = (*popup).hmenu;
00320         
00321         uncheckallmenuitems (hmenu);
00322         
00323         CheckItem (hmenu, (*popup).checkeditem, true);
00324         
00325         InsertMenu (hmenu, -1); /*see IM-V, p 236*/
00326         
00327         setcursortype (cursorisarrow); /*arrow cursor is more appropriate here*/
00328         
00329         pt.v = (*popup).popuprect.top;
00330         
00331         pt.h = (*popup).popuprect.left; 
00332         
00333         if ((*popup).checkeditem == 0) { /*no item selected*/
00334             
00335             CalcMenuSize (hmenu); 
00336         
00337             pt.v -= (**hmenu).menuHeight / 2;
00338             }
00339             
00340         LocalToGlobal (&pt); 
00341         
00342         pushstyle (geneva, 9, 0);
00343         
00344         /*jump into the roms*/ {
00345             
00346             long result;
00347             short lo, hi;
00348             
00349             result = PopUpMenuSelect (hmenu, pt.v, pt.h, (*popup).checkeditem);
00350             
00351             lo = LoWord (result);
00352             
00353             hi = HiWord (result);
00354             
00355             flcommandselected = hi > 0; /*something was selected*/
00356             
00357             (*popup).itemselected = lo;
00358             }
00359         
00360         popstyle ();
00361         
00362         if (flcommandselected)
00363             (*popup).menuselectcallback ();
00364         
00365         DeleteMenu ((*popup).idmenu);
00366         
00367         if ((*popup).fldisposemenu)
00368             DisposeMenu (hmenu);
00369             
00370         InvalRect (&(*popup).popuprect);
00371         
00372         return (true);
00373         }
00374     
00375     return (false);
00376     } /*popupclick*/
00377     
00378 
00379 boolean adjustpopupcursor (typopuprecord *popup) {
00380     
00381     if (!PtInRect (mousestatus.localpt, &(*popup).popuprect)) 
00382         return (false);
00383     
00384     setcursortype (cursorispopup);
00385     
00386     return (true);
00387     } /*adjustpopupcursor*/
00388 
00389 
00390 
00391 

Generated on Wed May 31 18:19:43 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6