ioapopup.c

Go to the documentation of this file.
00001 
00002 /*  $Id: ioapopup.c 1197 2006-04-05 22:01:22Z karstenw $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include <iac.h>
00032 #include <ioa.h>
00033 #include "ioapopup.h"
00034 #include "appletmemory.h"
00035 #include "quickdraw.h"
00036 
00037 #define idpopupmenu 25000
00038 
00039 #define popuparrowwidth 16 
00040 
00041 #define popupdrawinset 5
00042 
00043 #define horizinset 3 
00044 
00045 
00046 typedef struct typackedpopupdata {
00047     
00048     short versionnumber;
00049     
00050     unsigned short haslabel;
00051     
00052     bigstring bspopup;
00053     
00054     short checkeditem;
00055     
00056     short popupwidth;
00057     
00058     long lenmenuitems;
00059 
00060     char waste [10];
00061     } typackedpopupdata;
00062     
00063 
00064 typedef struct typackedB14popupdata { /*layout of a 1.0b14 popup record*/
00065     
00066     bigstring bs;
00067     
00068     Rect popuprect;
00069     
00070     unsigned short flarrows;
00071     
00072     short fontnum, fontsize, fontstyle;
00073     
00074     Rect leftarrowrect;
00075     
00076     Rect rightarrowrect;
00077     
00078     short checkeditem;
00079     
00080     short itemselected;
00081     
00082     short idmenu;
00083     
00084     unsigned short fldisposemenu;
00085     
00086     MenuHandle hmenu;
00087     
00088     ProcPtr getmenucallback;
00089     
00090     ProcPtr leftarrowcallback;
00091     
00092     ProcPtr rightarrowcallback;
00093     
00094     ProcPtr menuselectcallback;
00095     } typackedB14popupdata;
00096 
00097 
00098 typedef char smalliconbits [32];
00099 
00100 typedef smalliconbits *ptrsmalliconbits, **hdlsmalliconbits;
00101 
00102 #if !TARGET_API_MAC_CARBON
00103 
00104 static boolean plotsmallicon (Rect r, short iconlist, short iconnum, boolean flinvert) {
00105 
00106     hdlsmalliconbits hbits;
00107     short mode;
00108     BitMap bmap;
00109     GrafPtr w;
00110     
00111     GetPort (&w);
00112     
00113     hbits = (hdlsmalliconbits) GetResource ('SICN', iconlist);
00114     
00115     if (hbits == nil) /*failed to load the resource*/  
00116         return (false);
00117         
00118     r.right = r.left + widthsmallicon; /*we only pay attention to the top, left fields of rectangle*/
00119     
00120     r.bottom = r.top + heightsmallicon;
00121         
00122     bmap.baseAddr = (Ptr) &(*hbits) [iconnum];
00123     
00124     bmap.rowBytes = 2;
00125     
00126     bmap.bounds.top = bmap.bounds.left = 0; 
00127     
00128     bmap.bounds.bottom = r.bottom - r.top; 
00129     
00130     bmap.bounds.right = r.right - r.left;
00131     
00132     if (flinvert)
00133         mode = notSrcCopy;
00134     else 
00135         mode = srcOr; 
00136     
00137     //Code change by Timothy Paustian Saturday, May 20, 2000 10:06:20 PM
00138     //Changed to Opaque call for Carbon
00139     //I have not tested this yet.   
00140     #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00141     CopyBits(&bmap, GetPortBitMapForCopyBits(w), &bmap.bounds, &r, mode, nil);
00142     #else
00143     CopyBits (&bmap, &(*w).portBits, &bmap.bounds, &r, mode, nil);
00144     #endif
00145     return (true);
00146     } /*plotsmallicon*/
00147 
00148 #endif
00149 
00150 
00151 #ifndef isFrontier
00152 
00153 static void disposehandle (Handle h) {  /* already defined in memory.c when compiling Frontier */
00154     
00155     if (h != nil) DisposeHandle (h);
00156     } /*disposehandle*/
00157 
00158 #endif
00159     
00160     
00161 static boolean pushchar (byte ch, bigstring bs) {
00162     
00163     short newlen = bs [0] + 1;
00164     
00165     if (newlen > lenbigstring)
00166         return (false);
00167     
00168     bs [newlen] = ch;
00169     
00170     bs [0] = newlen;
00171     
00172     return (true);
00173     } /*pushchar*/
00174     
00175     
00176 static boolean getmenuitem (MenuHandle hmenu, short ixmenu, bigstring bs) {
00177     
00178     if (ixmenu <= 0)
00179         return (false);
00180         
00181     GetMenuItemText (hmenu, ixmenu, bs);
00182         
00183     return (true);
00184     } /*getmenuitem*/
00185 
00186 
00187 static void uncheckallmenuitems (MenuHandle hmenu) {
00188     
00189     short i;
00190     short ct;
00191     //Code change by Timothy Paustian Sunday, June 25, 2000 10:50:50 PM
00192     //updated to modern functions.
00193     ct = CountMenuItems (hmenu);
00194     
00195     for (i = 1; i <= ct; i++)
00196         CheckMenuItem (hmenu, i, false);
00197     } /*uncheckallmenuitems*/
00198     
00199     
00200 static boolean equalstrings (bs1, bs2) bigstring bs1, bs2; {
00201 
00202     /*
00203     return true if the two strings (pascal type, with length-byte) are
00204     equal.  return false otherwise.
00205     */
00206 
00207     ptrchar p1 = (ptrchar) bs1, p2 = (ptrchar) bs2;
00208     char ct = *p1 + 1;
00209     
00210     while (ct--) 
00211         
00212         if (*p1++ != *p2++)
00213         
00214             return (false);
00215         
00216     return (true); /*loop terminated*/
00217     } /*equalstrings*/
00218     
00219     
00220 static boolean pushpopupitem (hdlobject h, bigstring bs, boolean flenabled) {
00221     
00222     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00223     MenuHandle hmenu = (**hdata).hmenu;
00224     bigstring bsspace;
00225     
00226     if (equalstrings (bs, "\p(-")) /*take disabled seperator as is*/
00227         AppendMenu (hmenu, bs);
00228     
00229     else { /*to allow meta-characters in bs, append blank item, then set item text*/
00230         
00231         setstringwithchar (chspace, bsspace);
00232         
00233         AppendMenu (hmenu, bsspace);
00234         //Code change by Timothy Paustian Sunday, June 25, 2000 10:51:36 PM
00235         //Updated to modern calls
00236         if (!isemptystring (bs))
00237             SetMenuItemText (hmenu, CountMenuItems (hmenu), bs);
00238         }
00239     //Code change by Timothy Paustian Sunday, June 25, 2000 10:52:07 PM
00240     //updated
00241     if (!flenabled) {
00242         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00243         DisableMenuItem (hmenu, CountMenuItems (hmenu));
00244         #else
00245         DisableItem (hmenu, CountMenuItems (hmenu));
00246         #endif
00247         }
00248 
00249     return (true);
00250     } /*pushpopupitem*/
00251     
00252     
00253 boolean getnthpopupitem (hdlobject h, short n, bigstring bs) {
00254     
00255     /*
00256     get the nth string from the popup menu object. it's a bit slower to load
00257     up the menu using calls to this guy, but it's simpler, and it's nice to
00258     have this mess confined to one routine.
00259     
00260     n is 1-based.
00261     */
00262     
00263     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00264     Handle htext = (**hdata).hmenuitems;
00265     short i;
00266     short ctchars;
00267     short itemnum = 1;
00268     
00269     ctchars = GetHandleSize (htext);
00270     
00271     setstringlength (bs, 0);
00272         
00273     for (i = 0; i < ctchars; i++) {
00274         
00275         char ch = (*htext) [i];
00276         
00277         if (ch == ';') {
00278             
00279             if (itemnum == n)
00280                 return (true);
00281                 
00282             itemnum++;
00283             
00284             setstringlength (bs, 0);
00285             }
00286         else
00287             pushchar (ch, bs);
00288         } /*for*/
00289     
00290     return ((itemnum == n) && (stringlength (bs) > 0));
00291     } /*getnthpopupitem*/
00292     
00293         
00294 static boolean getpopupmenu (hdlobject h) {
00295     
00296     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00297     MenuHandle hmenu;
00298     bigstring bs;
00299     short n;
00300     
00301     hmenu = NewMenu (idpopupmenu, "\px");
00302     
00303     (**hdata).hmenu = hmenu;
00304         
00305     if (hmenu == nil)
00306         return (false);
00307 
00308     n = 1;
00309     
00310     while (getnthpopupitem (h, n++, bs)) {
00311     
00312         if (!pushpopupitem (h, bs, true))
00313             return (false);
00314         } /*while*/
00315     
00316     return (true);
00317     } /*getpopupmenu*/
00318     
00319     
00320 static void idealpopupsize (hdlobject hobject, short *height, short *width) {
00321     
00322     hdlpopupdata hdata = (hdlpopupdata) (**hobject).objectdata;
00323     short h, w;
00324     short maxwidth;
00325     FontInfo fi;
00326     
00327     GetFontInfo (&fi);
00328     
00329     h = fi.ascent + fi.descent + 4;
00330     
00331     maxwidth = StringWidth ((**hdata).bspopup);
00332     
00333     if (getpopupmenu (hobject)) { /*use the strings in the menu to determine width*/
00334         
00335         MenuHandle hmenu = (**hdata).hmenu;
00336         short i;
00337         short sw;
00338         short lastitem;
00339         bigstring bs;
00340         //Code change by Timothy Paustian Sunday, June 25, 2000 10:52:18 PM
00341         //updated
00342         lastitem = CountMenuItems (hmenu);
00343         
00344         for (i = 1; i <= lastitem; i++) {
00345             
00346             getmenuitem (hmenu, i, bs);
00347             
00348             sw = StringWidth (bs);
00349             
00350             if (sw > maxwidth)
00351                 maxwidth = sw;
00352             } /*for*/
00353         
00354         DisposeMenu (hmenu);
00355         }
00356         
00357     w = maxwidth + popuparrowwidth + popupdrawinset + 8;
00358     
00359     *height = h;
00360     
00361     *width = w;
00362     } /*idealpopupsize*/
00363     
00364     
00365 static boolean cleanpopup (hdlobject h, short height, short width, Rect *r) {
00366     
00367     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00368     short gridunits = (**(**h).owningcard).gridunits;
00369     short popupheight, popupwidth;
00370     
00371     idealpopupsize (h, &popupheight, &popupwidth);
00372     
00373     popupwidth = IOAmakemultiple (popupwidth, gridunits);
00374     
00375     if ((**hdata).haslabel) {
00376     
00377         width += horizinset + popupwidth;
00378         
00379         width = IOAmakemultiple (width, gridunits);
00380         }
00381     else
00382         width = popupwidth;
00383     
00384     (*r).right = (*r).left + width; 
00385 
00386     (*r).bottom = (*r).top + height;
00387     
00388     /*side-effect -- we use the popup width when drawing the object*/ {
00389         
00390         hdlpopupdata lhdata = (hdlpopupdata) (**h).objectdata;
00391         
00392         (**lhdata).popupwidth = popupwidth;
00393         }
00394     
00395     return (true);
00396     } /*cleanpopup*/
00397     
00398 
00399 static void getpopuprects (hdlobject h, Rect *rtext, Rect *rpopup) {
00400     
00401     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00402     Rect robject = (**h).objectrect;
00403     
00404     if ((**hdata).haslabel) {
00405     
00406         *rpopup = robject; /*set right, top, bottom*/
00407     
00408         (*rpopup).left = (*rpopup).right - (**hdata).popupwidth;
00409     
00410         *rtext = robject; /*set left, top, bottom*/
00411     
00412         (*rtext).right = (*rpopup).left - horizinset;
00413         }
00414     else {
00415         *rpopup = robject; /*the popup takes up the whole rectangle*/
00416         
00417         IOAclearbytes (rtext, longsizeof (Rect));
00418         }
00419     } /*getpopuprects*/
00420     
00421     
00422 static boolean clickpopup (hdlobject listhead, hdlobject h, Point pt, boolean flshiftkey, boolean fl2click) {
00423 #pragma unused(listhead, flshiftkey, fl2click)
00424 
00425     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00426     hdlcard hc = (**h).owningcard;
00427     MenuHandle hmenu;
00428     
00429     (**hc).runmodechanges = true; /*indicate that one of the objects in the card changed*/
00430     
00431     if (!getpopupmenu (h)) /*error, but consume the mouse click*/
00432         return (true);
00433         
00434     hmenu = (**hdata).hmenu;
00435     
00436     uncheckallmenuitems (hmenu);
00437     //Code change by Timothy Paustian Sunday, June 25, 2000 10:51:50 PM
00438     //updated to modern call
00439     CheckMenuItem (hmenu, (**hdata).checkeditem, true);
00440     
00441     InsertMenu (hmenu, -1); /*see IM-V, p 236*/
00442     
00443     /*setcursortype (cursorisarrow);*/ /*arrow cursor is more appropriate here*/
00444     
00445     /*set pt to point at the upper left corner of the popup rect*/ {
00446         
00447         Rect r = (**h).objectrect;
00448         int         menuHeight;
00449         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00450         menuHeight = GetMenuHeight(hmenu);
00451         #else
00452         menuHeight = (**hmenu).menuHeight;
00453         #endif
00454         
00455         pt.v = r.top;
00456         
00457         pt.h = r.right - (**hdata).popupwidth;
00458     
00459         if ((**hdata).checkeditem == 0) { /*no item selected*/
00460             
00461             CalcMenuSize (hmenu); 
00462         
00463             pt.v -= menuHeight / 2;
00464             }
00465             
00466         LocalToGlobal (&pt); 
00467         }
00468         
00469     /*standard UI -- invert the label text*/ {
00470         
00471         if ((**hdata).haslabel) {
00472         
00473             Rect rtext, rpopup;
00474         
00475             getpopuprects (h, &rtext, &rpopup);
00476         
00477             InvertRect (&rtext);
00478             }
00479         }
00480     
00481     /*jump into the roms*/ {
00482         
00483         long result;
00484         short lo, hi;
00485         
00486         result = PopUpMenuSelect (hmenu, pt.v, pt.h, (**hdata).checkeditem);
00487         
00488         lo = LoWord (result);
00489         
00490         hi = HiWord (result);
00491         
00492         if (hi > 0) { /*something was selected*/
00493             
00494             bigstring bs;
00495             
00496             (**hdata).checkeditem = lo;
00497             
00498             getmenuitem (hmenu, lo, bs);
00499             
00500             IOAcopystring (bs, (**hdata).bspopup);
00501             
00502             IOArunbuttonscript (h); /*1.0b15 -- run the action script*/
00503             }
00504         }
00505     
00506     DeleteMenu (idpopupmenu);
00507     
00508     DisposeMenu (hmenu);
00509         
00510     IOAinvalobject (h);
00511     
00512     (**(**h).owningcard).runtimevaluechanged = true; /*DW 10/15/95*/
00513     
00514     return (true);
00515     } /*clickpopup*/
00516     
00517 
00518 #if TARGET_API_MAC_CARBON == 1
00519 
00520     static void MyThemeButtonDrawCallback (const Rect *bounds, ThemeButtonKind kind, const ThemeButtonDrawInfo *info,
00521         UInt32 refcon, SInt16 depth, Boolean isColorDev) {
00522 #pragma unused(kind, info, depth, isColorDev)
00523 
00524         /*
00525         7.0b48 PBS: draw the label for a popup menu.
00526         */
00527         
00528         StringPtr sptr = (StringPtr) refcon;
00529         
00530         pushstyle (geneva, 10, 0);
00531 
00532         movepento ((*bounds).left, (*bounds).top + 12);
00533         
00534         pendrawstring (sptr);
00535 
00536         popstyle ();
00537         } /*MyThemeButtonDrawCallback*/
00538 
00539 #endif
00540 
00541 
00542 static boolean drawpopup (hdlobject h) {
00543 
00544     /*
00545     2002-10-13 AR: Reorganized variable declarations in draw popup code
00546     to eliminate compiler warnins about unused variables.
00547     */
00548     
00549     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00550     Rect rtext, rpopup;
00551     
00552     getpopuprects (h, &rtext, &rpopup);
00553     
00554     /*draw the popup menu*/ {
00555     
00556         #if TARGET_API_MAC_CARBON == 1
00557         
00558             Rect r = rpopup;
00559             ThemeButtonDrawUPP drawupp;
00560             ThemeButtonDrawInfo drawinfo;
00561             
00562             drawupp = NewThemeButtonDrawUPP (MyThemeButtonDrawCallback);
00563                     
00564             drawinfo.state = kThemeButtonOn;
00565             
00566             drawinfo.value = kThemeStateActive;
00567             
00568             drawinfo.adornment = 0;
00569             
00570             //setrect (&r, rpopup.top, rpopup.left, rpopup.bottom + 1, rpopup.right + 1);
00571             
00572             //eraserect (r);
00573             
00574             DrawThemeButton (&r, kThemePopupButton, &drawinfo, nil, nil, drawupp, (unsigned long) (**hdata).bspopup);
00575             
00576             //DisposeThemeButtonDrawUPP (MyThemeButtonDrawCallback);
00577             DisposeThemeButtonDrawUPP (drawupp);
00578         
00579         #else
00580         
00581             Rect r = rpopup;
00582             FontInfo fi;
00583             bigstring bs;
00584 
00585             GetFontInfo (&fi);
00586             
00587             EraseRect (&r);
00588             
00589             InsetRect (&r, 1, 1);
00590             
00591             r.left = r.right - popuparrowwidth;
00592             
00593             plotsmallicon (r, 129, 0, false); /*display the down-pointing wedge inside the popup*/
00594         
00595             r = rpopup;
00596             
00597             FrameRect (&r);
00598             
00599             MoveTo (r.left + 1, r.bottom);
00600             
00601             LineTo (r.right, r.bottom);
00602             
00603             LineTo (r.right, r.top + 1);
00604             
00605             r.right -= popuparrowwidth;
00606             
00607             InsetRect (&r, 4, 2);
00608         
00609             MoveTo (r.left, r.bottom - fi.descent - 1);
00610             
00611             IOAcopystring ((**hdata).bspopup, bs);
00612             
00613             IOAellipsize (bs, r.right - r.left);
00614             
00615             DrawString (bs);
00616         
00617         #endif
00618         }
00619     
00620     /*draw the text*/ {
00621         
00622         if ((**hdata).haslabel) {
00623         
00624             if (!(**h).objecttransparent)
00625                 EraseRect (&rtext);
00626             
00627             if (!(**(**h).owningcard).flskiptext) 
00628                 IOAeditdrawtexthandle ((**h).objectvalue, rtext, (**h).objectjustification);
00629             }
00630         }
00631     
00632     return (true);
00633     } /*drawpopup*/
00634     
00635     
00636 static boolean newpopupdata (hdlpopupdata *hdata) {
00637 
00638     hdlpopupdata h;
00639     
00640     h = (hdlpopupdata) NewHandleClear (longsizeof (typopupdata));
00641     
00642     if (h == nil)
00643         return (false);
00644     
00645     (**h).haslabel = true;
00646     
00647     (**h).checkeditem = 1;
00648     
00649     *hdata = h;
00650     
00651     return (true);
00652     } /*newpopupdata*/
00653     
00654     
00655 static boolean initpopup (tyobject *obj) {
00656     
00657     hdlpopupdata hdata;
00658     Handle hmenuitems;
00659     
00660     if (!newpopupdata (&hdata))
00661         return (false);
00662     
00663     (*obj).objectdata = (Handle) hdata;
00664     
00665     IOAnewtexthandle ("\pRed;Green;Blue", &hmenuitems);
00666     
00667     (**hdata).hmenuitems = hmenuitems;
00668     
00669     (**hdata).checkeditem = 1;
00670     
00671     IOAcopystring ("\pRed", (**hdata).bspopup);
00672     
00673     return (true); /*we do want to edit it*/
00674     } /*initpopup*/
00675 
00676 
00677 static boolean recalcpopup (hdlobject h, boolean flmajorrecalc) {
00678 #pragma unused(flmajorrecalc)
00679 
00680     bigstring errorstring;
00681     Handle htoss;
00682 
00683     if (!IOAevalscript (h, (**h).objectrecalcscript, &htoss, (**h).objectlanguage, errorstring))
00684         return (false);
00685     
00686     disposehandle (htoss);
00687     
00688     return (true); 
00689     } /*recalcpopup*/
00690 
00691 
00692 #if 0
00693 
00694 static boolean xxxrecalcpopup (hdlobject h, boolean flmajorrecalc) {
00695     
00696     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00697     Handle hmenuitems;
00698     
00699     if (!IOArecalcobjectvalue (h))
00700         return (false);
00701     
00702     if (!copyhandle ((**h).objectdata, &hmenuitems))
00703         return (false);
00704     
00705     disposehandle ((**hdata).hmenuitems); 
00706     
00707     (**hdata).hmenuitems = hmenuitems;
00708     
00709     (**hdata).checkeditem = 1;
00710     
00711     getnthpopupitem (h, (**hdata).checkeditem, (**hdata).bspopup);
00712     
00713     IOAinvalobject (h);
00714     
00715     return (true); 
00716     } /*xxxrecalcpopup*/
00717 
00718 #endif
00719 
00720 
00721 static boolean getpopupinvalrect (hdlobject h, Rect *r) {
00722     
00723     *r = (**h).objectrect;
00724     
00725     (*r).right += 3; /*4/2/93 DW: work around display bug in framework?*/
00726     
00727     (*r).bottom += 3;
00728     
00729     return (true);
00730     } /*getpopupinvalrect*/
00731 
00732 
00733 static boolean canreplicatepopup (hdlobject h) {
00734 #pragma unused(h)
00735 
00736     return (true); 
00737     } /*canreplicatepopup*/
00738 
00739 
00740 static boolean getpopupeditrect (hdlobject h, Rect *redit) {
00741     
00742     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00743     Rect rpopup;
00744     
00745     if ((**hdata).haslabel) {
00746     
00747         getpopuprects (h, redit, &rpopup);
00748     
00749         return (true); /*it can be edited*/
00750         }
00751     else
00752         return (false); /*it can't be edited*/
00753     } /*getpopupeditrect*/
00754     
00755 
00756 static boolean getpopupvalue (hdlobject h, Handle *hvalue) {
00757     
00758     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00759     bigstring bs;
00760     
00761     IOAcopystring ("\p\"", bs);
00762 
00763     IOApushstring ((**hdata).bspopup, bs);
00764     
00765     IOApushstring ("\p\"", bs);
00766     
00767     return (IOAnewtexthandle (bs, hvalue));
00768     } /*getpopupvalue*/
00769     
00770 
00771 static boolean debugpopup (hdlobject h, bigstring errorstring) {
00772 #pragma unused(h)
00773 
00774     setstringlength (errorstring, 0);
00775     
00776     return (true);
00777     } /*debugpopup*/
00778     
00779 
00780 static boolean getpopupattributes (hdlobject h, AppleEvent *event) {
00781     
00782     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00783     Handle hselectionstring, hsemicolonstring;
00784     
00785     IOAnewtexthandle ((**hdata).bspopup, &hselectionstring);
00786 
00787     hsemicolonstring = (**hdata).hmenuitems; HandToHand (&hsemicolonstring);
00788     
00789     IACglobals.event = event; 
00790     
00791     if (!IACpushbooleanparam ((**hdata).haslabel, 'hlbl'))
00792         return (false);
00793         
00794     if (!IACpushtextparam (hselectionstring, 'sels')) /*the selected string*/
00795         return (false);
00796 
00797     if (!IACpushshortparam ((**hdata).checkeditem, 'seln')) /*the selected number*/
00798         return (false);
00799     
00800     if (!IACpushtextparam (hsemicolonstring, 'mens')) /*the semi-colon separated string*/
00801         return (false);
00802 
00803     return (true);
00804     } /*getpopupattributes*/
00805     
00806     
00807 static boolean setpopupattributes (hdlobject h, AppleEvent *event) {
00808     
00809     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00810     Boolean haslabel;
00811     short checkeditem;
00812     Handle hmenuitems;
00813     
00814     IACglobals.event = event; 
00815     
00816     IACglobals.nextparamoptional = true;
00817     
00818     if (IACgetbooleanparam ('hlbl', &haslabel)) 
00819         (**hdata).haslabel = haslabel; 
00820     
00821     IACglobals.nextparamoptional = true;
00822     
00823     if (IACgetshortparam ('seln', &checkeditem)) 
00824         (**hdata).checkeditem = checkeditem; 
00825         
00826     IACglobals.nextparamoptional = true;
00827     
00828     if (IACgettextparam ('mens', &hmenuitems)) {
00829         
00830         disposehandle ((**hdata).hmenuitems);
00831         
00832         (**hdata).hmenuitems = hmenuitems;
00833         }
00834     
00835     getnthpopupitem (h, (**hdata).checkeditem, (**hdata).bspopup);
00836 
00837     return (true);
00838     } /*setpopupattributes*/
00839     
00840     
00841 static boolean packpopupdata (hdlobject hobject, Handle *hpackeddata) {
00842     
00843     hdlpopupdata hdata = (hdlpopupdata) (**hobject).objectdata;
00844     Handle hmenuitems = (**hdata).hmenuitems;
00845     short lenmenuitems;
00846     typackedpopupdata info;
00847     Handle hpacked;
00848     Ptr p;
00849     
00850     *hpackeddata = nil;
00851     
00852     IOAclearbytes (&info, longsizeof (info));
00853     
00854     info.versionnumber = 1;
00855     
00856     info.haslabel = (**hdata).haslabel;
00857     
00858     IOAcopystring ((**hdata).bspopup, info.bspopup);
00859     
00860     info.checkeditem = (**hdata).checkeditem;
00861     
00862     info.popupwidth = (**hdata).popupwidth;
00863     
00864     if (hmenuitems == nil)
00865         lenmenuitems = 0;
00866     else
00867         lenmenuitems = GetHandleSize (hmenuitems);
00868         
00869     info.lenmenuitems = lenmenuitems;
00870         
00871     hpacked = NewHandle (longsizeof (info) + lenmenuitems);
00872     
00873     if (hpacked == nil)
00874         return (false);
00875     
00876     HLock (hpacked);
00877     
00878     p = *hpacked;
00879     
00880     BlockMove (&info, p, longsizeof (info));
00881     
00882     p += longsizeof (info);
00883     
00884     if (lenmenuitems > 0) 
00885         BlockMove (*hmenuitems, p, lenmenuitems);
00886     
00887     HUnlock (hpacked);
00888     
00889     *hpackeddata = hpacked;
00890     
00891     return (true);
00892     } /*packpopupdata*/
00893     
00894     
00895 static boolean disposepopupdata (hdlobject h) {
00896     
00897     hdlpopupdata hdata = (hdlpopupdata) (**h).objectdata;
00898     
00899     disposehandle ((**hdata).hmenuitems);
00900     
00901     return (true);
00902     } /*disposepopupdata*/
00903     
00904     
00905 static boolean unpackpopupdata (hdlobject h) {
00906     
00907     /*
00908     4/27/93 DW: has code to handle pre-1.0b15 popup records. after
00909     all are converted this code should be removed. look for "zzz" 
00910     comments.
00911     */
00912     
00913     hdlpopupdata hdata;
00914     Handle hpackeddata;
00915     typackedpopupdata info;
00916     Handle hmenuitems;
00917     Ptr p;
00918         
00919     hpackeddata = (**h).objectdata; 
00920     
00921     if (!newpopupdata (&hdata)) 
00922         return (false);
00923         
00924     (**h).objectdata = (Handle) hdata;
00925     
00926     HLock (hpackeddata);
00927     
00928     p = *hpackeddata;
00929     
00930     BlockMove (p, &info, longsizeof (info));
00931     
00932     p += longsizeof (info);
00933     
00934     if (info.versionnumber != 1) { /*zzz*/
00935         
00936         Rect robject = (**h).objectrect;
00937         
00938         info.lenmenuitems = 0;
00939         
00940         info.haslabel = false;
00941         
00942         setstringlength (info.bspopup, 0);
00943         
00944         info.checkeditem = 1;
00945         
00946         info.popupwidth = robject.right - robject.left;
00947         }
00948     
00949     if (info.lenmenuitems > 0) 
00950         PtrToHand (p, &hmenuitems, info.lenmenuitems);
00951     else
00952         hmenuitems = nil;
00953         
00954     HUnlock (hpackeddata);
00955     
00956     (**hdata).hmenuitems = hmenuitems;
00957     
00958     (**hdata).haslabel = info.haslabel;
00959 
00960     IOAcopystring (info.bspopup, (**hdata).bspopup);
00961 
00962     (**hdata).checkeditem = info.checkeditem;
00963 
00964     (**hdata).popupwidth = info.popupwidth;
00965     
00966     disposehandle (hpackeddata);
00967     
00968     return (true);
00969     } /*unpackpopupdata*/
00970     
00971     
00972 void setuppopup (tyioaconfigrecord *);
00973 
00974 
00975 void setuppopup (tyioaconfigrecord *config) {
00976 
00977     IOAcopystring ("\pPopup menu", (*config).objectTypeName);
00978     
00979     (*config).objectTypeID = popuptype;
00980     
00981     (*config).frameWhenEditing = true;
00982     
00983     (*config).canEditValue = false;
00984     
00985     (*config).toggleFlagWhenHit = false;
00986     
00987     (*config).mutuallyExclusive = false;
00988     
00989     (*config).speaksForGroup = false;
00990     
00991     (*config).handlesMouseTrack = true; /*allow the popup manager to track the mouse*/
00992     
00993     (*config).hasSpecialCard = true;
00994 
00995     (*config).initObjectCallback = initpopup;
00996     
00997     (*config).drawObjectCallback = drawpopup;
00998     
00999     (*config).clickObjectCallback = clickpopup;
01000     
01001     (*config).recalcObjectCallback = recalcpopup;
01002     
01003     (*config).cleanupObjectCallback = cleanpopup;
01004     
01005     (*config).canReplicateObjectCallback = canreplicatepopup;
01006     
01007     (*config).getObjectEditRectCallback = getpopupeditrect;
01008     
01009     (*config).getValueForScriptCallback = getpopupvalue;
01010     
01011     (*config).debugObjectCallback = debugpopup; 
01012     
01013     (*config).getObjectInvalRectCallback = getpopupinvalrect;
01014     
01015     (*config).getAttributesCallback = getpopupattributes;
01016     
01017     (*config).setAttributesCallback = setpopupattributes;
01018     
01019     (*config).unpackDataCallback = unpackpopupdata;
01020     
01021     (*config).packDataCallback = packpopupdata;
01022     
01023     (*config).disposeDataCallback = disposepopupdata;
01024     } /*setuppopup*/
01025     
01026     

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