popup.c

Go to the documentation of this file.
00001 
00002 /*  $Id: popup.c 1260 2006-04-13 06:13:10Z sethdill $    */
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 "quickdraw.h"
00032 #include "font.h"
00033 #include "cursor.h"
00034 #include "menu.h"
00035 #include "mouse.h"
00036 #include "bitmaps.h"
00037 #include "strings.h"
00038 #include "smallicon.h"
00039 #include "popup.h"
00040 #include "frontierwindows.h"
00041 #include "windowlayout.h"
00042 #include "shell.h"
00043 
00044 
00045 boolean pushpopupitem (hdlmenu hmenu, bigstring bs, boolean flenabled, short commandid) {
00046 
00047     /*
00048     7.1b23 PBS: commandid is new parameter: allow caller to specify the command id of
00049     the menu item. This is needed for hierarchical popup menus. It's passed to pushmenuitem.
00050     */
00051     
00052     if (!pushmenuitem (hmenu, defaultpopupmenuid, bs, commandid))
00053         return (false);
00054     
00055     if (!flenabled)
00056         disablemenuitem (hmenu, countmenuitems (hmenu));
00057     
00058     return (true);
00059     } /*pushpopupitem*/
00060 
00061 
00062 static short handlepopup (hdlmenu hmenu, Rect r, short item) {
00063     
00064     /*
00065     display the popup menu and let the user interact with it.  return the item
00066     number the user selected.
00067     
00068     the indicated item is highlighted when the menu pops up.
00069     
00070     note that the menu must be inserted in the menu list before you call us.  this
00071     is done by InsertMenu (hmenu, -1).
00072     
00073     7.1b23 PBS: For hierarchical menu support, some callers want the *commandID*
00074     of the item rather than its position -- since, with sub-menus, multiple items
00075     will have the same position. (First item in the menu and the first item in a submenu
00076     both have the position of 1.) So, if the commandID has been set, return that
00077     instead of the position.
00078     
00079     2002-10-12 AR: We can only return the commandID, if an item was actually selected
00080     from the popup menu. On the Mac, if nothing was selected, GetMenuHandle returns
00081     a nil handle and the subsequent call to GetMenuItemCommandID would return an OS error
00082     instead of setting the commandID. Now, we check the menu handle before calling
00083     GetMenuItemCommandID, and we only return the commandID (instead of iditem) if
00084     the GetMenuItemCommandID call actually succeeded.
00085     */
00086     
00087     Point pt;
00088 
00089 #ifdef MACVERSION
00090     short idmenu;
00091     short iditem;
00092     long menuresult;
00093     long commandid;
00094     hdlmenu hchosenmenu;
00095 #endif
00096     
00097     setcursortype (cursorisarrow); /*arrow cursor is more appropriate here*/
00098     
00099     pt.v = r.top;
00100     
00101     pt.h = r.left; 
00102     
00103 #ifdef MACVERSION
00104     if (item == 0) { /*no item selected*/
00105         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00106         SInt16 menuHeight;
00107         CalcMenuSize (hmenu); 
00108         //Code change by Timothy Paustian Monday, May 1, 2000 9:44:34 PM
00109         //Changed to Opaque call for Carbon
00110         //This needs to be tested.
00111         menuHeight = GetMenuHeight(hmenu);
00112         pt.v -= menuHeight / 2;
00113         #else
00114         //old code
00115         pt.v -= (**hmenu).menuHeight / 2;
00116         #endif
00117         }
00118         
00119     localtoglobalpoint (getfrontwindow (), &pt);
00120     
00121     menuresult = PopUpMenuSelect (hmenu, pt.v, pt.h, item);
00122     
00123     idmenu = HiWord (menuresult);
00124     
00125     iditem = LoWord (menuresult);
00126     
00127     hchosenmenu = GetMenuHandle (idmenu);
00128     
00129     if (hchosenmenu != nil) /* 2002-10-12 AR */
00130         if (GetMenuItemCommandID (hchosenmenu, iditem, (MenuCommand *)(&commandid)) == noErr)
00131             if (commandid > 0)
00132                 return (commandid);
00133     /*
00134     GetMenuItemCommandID (hchosenmenu, iditem, &commandid);
00135     
00136     if (commandid > 0)
00137         return (commandid);
00138     */
00139     
00140     //return (LoWord (PopUpMenuSelect (hmenu, pt.v, pt.h, item)));
00141     
00142     return (iditem);
00143 #endif
00144 
00145 #ifdef WIN95VERSION
00146     {
00147     UINT flags = 0;
00148     short itemhit = 0;
00149 
00150     localtoglobalpoint (getfrontwindow (), &pt);
00151     
00152     hmenu = GetSubMenu (hmenu, 0); // get actual popup
00153     
00154     if (mousestatus.whichbutton == rightmousebuttonaction)
00155         flags |= TPM_RIGHTBUTTON;
00156     
00157     if (TrackPopupMenuEx (hmenu, flags, pt.h, pt.v, shellframewindow, NULL)) {
00158     
00159         MSG msg;
00160         
00161         if (PeekMessage (&msg, shellframewindow, WM_COMMAND, WM_COMMAND, PM_REMOVE))
00162             return (LOWORD (msg.wParam) % 100);
00163             
00164         }
00165         
00166     return (0);
00167     }
00168 #endif
00169 
00170     } /*handlepopup*/
00171 
00172 
00173 boolean popupmenuhit (Rect r, boolean flgeneva9, fillpopupcallback fillpopuproutine, popupselectcallback popupselectroutine) {
00174     
00175     /*
00176     12/19/91 dmb: don't do DeleteMenu if it wasn't inserted
00177     
00178     4/15/92 dmb: if checkeditem is negative, select it but don't check it
00179     */
00180     
00181     register boolean fl = true;
00182     hdlmenu hmenu;
00183     short checkeditem;
00184     short itemselected;
00185 #ifdef MACVERSION
00186     short idmenu;
00187 
00188     if (flgeneva9) {
00189         
00190         insetrect (&r, 0, 2);
00191         
00192         idmenu = defaultpopupmenuid; //geneva9popupmenuid;
00193         }
00194     else
00195         idmenu = defaultpopupmenuid;
00196     
00197     hmenu = getresourcemenu (idmenu); /*name is irrelevent in a popup*/
00198 #else
00199     flgeneva9 = false;
00200     
00201     hmenu = Newmenu (defaultpopupmenuid, "");
00202 
00203 #endif
00204 
00205     if (hmenu == nil)
00206         return (false);
00207     
00208     if (!(*fillpopuproutine) (hmenu, &checkeditem)) {
00209         
00210         fl = false;
00211         
00212         sysbeep ();
00213         
00214         goto exit;
00215         }
00216     
00217     if (checkeditem < 0)
00218         checkeditem = -checkeditem;
00219     
00220     else {
00221         
00222         //#if !TARGET_API_MAC_CARBON == 1
00223         
00224             //if (flgeneva9)
00225                 //markmenuitem (hmenu, checkeditem, '');
00226             //else
00227         
00228         //#endif
00229         
00230             checkmenuitem (hmenu, checkeditem, true);
00231         
00232         }
00233     
00234     #ifdef MACVERSION
00235         inserthierarchicmenu (hmenu, -1); /*see IM-V, p 236*/
00236         
00237 
00238         #if TARGET_API_MAC_CARBON == 1
00239         
00240             if (flgeneva9)
00241         
00242                 SetMenuFont (hmenu, 0, 10); /*smaller font in OS X*/
00243         
00244         #else
00245         
00246             if (flgeneva9) { /*Geneva*/
00247                 
00248                 short idgeneva;
00249                 
00250                 fontgetnumber ("\pGeneva", &idgeneva);
00251                 
00252                 SetMenuFont (hmenu, idgeneva, 9);
00253                 
00254                 } /*if*/
00255         #endif
00256     #endif
00257     
00258     itemselected = handlepopup (hmenu, r, checkeditem); /*menus are 1-based*/
00259     
00260     if (itemselected > 0) { /*something selected*/
00261         
00262         (*popupselectroutine) (hmenu, itemselected);
00263         }
00264 
00265     #ifdef MACVERSION
00266         removemenu (idmenu);
00267     #endif
00268     
00269     exit:
00270     
00271     disposemenu (hmenu);
00272     
00273     return (fl);
00274     } /*popupmenuhit*/
00275 
00276 
00277 #ifdef xxxWIN95VERSION
00278 
00279     short popupfont = -1;
00280 
00281     static void initpopupfont (void) {
00282         
00283         if (popupfont == -1) {
00284             
00285             fontgetnumber ("\x0d" "MS Sans Serif", &popupfont);
00286 
00287             if (popupfont == 0)
00288                 fontgetnumber ("\x05" "Ariel", &popupfont);
00289             }
00290         } /*initpopupfont*/
00291 
00292 #else
00293     #define initpopupfont() ((void *) 0)
00294 #endif
00295 
00296 
00297 #if TARGET_API_MAC_CARBON == 1
00298 
00299 static void
00300 MyThemeButtonDrawCallback (
00301         const Rect                  *bounds,
00302         ThemeButtonKind              kind,
00303         const ThemeButtonDrawInfo   *info,
00304         UInt32                       userData,
00305         SInt16                       depth,
00306         Boolean                      isColorDev)
00307 {
00308 #pragma unused (kind, info, depth, isColorDev)
00309 
00310     /*
00311      7.0b48 PBS: draw the label for a popup menu.
00312      */
00313 
00314     bigstring bs;
00315 
00316     pushstyle (popupfont, popupfontsize, 0);
00317 
00318     texthandletostring ((Handle) userData, bs);
00319 
00320     movepento ((*bounds).left, (*bounds).top + 10);
00321 
00322     pendrawstring (bs);
00323 
00324     popstyle ();
00325     } /*MyThemeButtonDrawCallback*/
00326 
00327 #endif
00328 
00329 
00330 boolean drawpopup (Rect rpopup, bigstring bs, boolean flbitmap) {
00331 #if TARGET_API_MAC_CARBON == 1
00332 #   pragma unused (flbitmap)
00333 
00334     Rect r;
00335     Handle h;
00336     ThemeButtonDrawUPP drawupp;
00337     ThemeButtonDrawInfo drawinfo;
00338 
00339     
00340     drawupp = NewThemeButtonDrawUPP (MyThemeButtonDrawCallback);
00341 
00342     drawinfo.state = kThemeButtonOn;
00343 
00344     drawinfo.value = kThemeStateActive;
00345 
00346     drawinfo.adornment = 0;
00347 
00348     setrect (&r, rpopup.top, rpopup.left, rpopup.bottom + 1, rpopup.right + 1);
00349 
00350     eraserect (r);
00351 
00352     newtexthandle (bs, &h); 
00353 
00354     DrawThemeButton (&r, kThemePopupButton, &drawinfo, nil, nil, drawupp, (unsigned long) h);
00355 
00356     //DisposeThemeButtonDrawUPP (MyThemeButtonDrawCallback);
00357     DisposeThemeButtonDrawUPP (drawupp);
00358 
00359     return (true);
00360 
00361 #else
00362 
00363     Rect r;
00364 
00365     initpopupfont ();
00366 
00367     setrect (&r, rpopup.top, rpopup.left, rpopup.bottom + 1, rpopup.right + 1);
00368 
00369     if (flbitmap)
00370         flbitmap = openbitmap (r, getport ());
00371 
00372     eraserect (r);
00373 
00374     r = rpopup;
00375 
00376     framerect (r);
00377 
00378     movepento (r.left + 1, r.bottom);
00379 
00380     pendrawline (r.right, r.bottom);
00381 
00382     pendrawline (r.right, r.top + 1);
00383 
00384     r.right -= popuparrowwidth;
00385 
00386     insetrect (&r, 4, 2);
00387 
00388     pushstyle (popupfont, popupfontsize, 0);
00389 
00390     movepento (r.left, r.bottom - globalfontinfo.descent - 1);
00391 
00392     ellipsize (bs, r.right - r.left);
00393 
00394     pendrawstring (bs);
00395 
00396     popstyle ();
00397 
00398     r = rpopup;
00399 
00400     insetrect (&r, 1, 1);
00401 
00402     r.left = r.right - popuparrowwidth;
00403 
00404     displaypopupicon (r, true);
00405 
00406     if (flbitmap)
00407         closebitmap (getport ());
00408 
00409     return (true);
00410 #endif
00411     } /*drawpopup*/
00412 
00413 
00414 boolean adjustpopupcursor (Point pt, Rect r) {
00415     
00416     /*
00417     r.left = r.right - popuparrowwidth;
00418     */
00419     
00420     if (!pointinrect (pt, r)) 
00421         return (false);
00422     
00423     setcursortype (cursorispopup);
00424     
00425     return (true);
00426     } /*adjustpopupcursor*/
00427 
00428 
00429 
00430 

Generated on Wed May 31 18:20:00 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6