boolean clickcolorpopup (Point pt, RGBColor *rgb) { long result; short lo, hi; if (!flpopupinit) flpopupinit = initcolorpopup (); setcursortype (cursorisarrow); CalcMenuSize (colormenu); InsertMenu (colormenu, hierMenu); LocalToGlobal (&pt); result = PopUpMenuSelect (colormenu, pt.v, pt.h, -1); DeleteMenu ((**colormenu).menuID); lo = LoWord (result); hi = HiWord (result); if (hi > 0) { /*something was selected*/ *rgb = (*ctable) [lo - 1].rgb; return (true); } return (false); } /*clickcolorpopup*/
static void DeleteSubMenus(SubSysMenuHandle subSysMenus) // Remove any sub-menus that we added to the menu bar. // Basically this just walks subSysMenus (backwards, which // isn't strictly necessary, but reassures me that the menu // bar is somewhat consistent at each step), deleting each // menu from the menu bar and reseting its parent to reference // menu ID 0. { ItemCount entryCount; ItemCount entryIndex; SubSysMenuEntry thisEntry; // Have to handle both NULL and non-NULL case. // This expression always evaluates to true, // but it captures the semantics of what this // routine must do. assert(subSysMenus != NULL || subSysMenus == NULL); entryCount = CountSubSysMenus(subSysMenus); for (entryIndex = 0; entryIndex < entryCount; entryIndex++) { thisEntry = (*subSysMenus)[entryCount - entryIndex - 1]; DeleteMenu( (**(thisEntry.childMenu)).menuID ); SetItemMark( thisEntry.parentMenu, thisEntry.itemInParent, 0); // Recalculate the parent menu size, for consistency with // the similar code in InsertSystemSubMenu. CalcMenuSize(thisEntry.parentMenu); } }
static boolean initcolorpopup (void) { CTabHandle syspal; Handle mdefh; if (!systemhascolor ()) return (false); syspal = GetCTable (8); HLock ((Handle) syspal); ctable = &(**syspal).ctTable; mdefh = appnewhandle (6); *(short *)*mdefh = 0x4EF9; *(long *)(*mdefh + sizeof (short)) = (long) &colormenuhandler; colormenu = GetMenu (256); /*256 blank entries in this menu*/ (**colormenu).menuProc = mdefh; CalcMenuSize (colormenu); /*create a picture, didn't make it faster, commented*/ { /* WindowPtr w; Rect r; w = GetNewCWindow (128, nil, (WindowPtr) -1); pushmacport (w); r.top = r.left = 0; r.bottom = (**colormenu).menuHeight; r.right = (**colormenu).menuWidth; ClipRect (&r); colorpopuppict = OpenPicture (&r); drawcolorpopup (r); ClosePicture (); popmacport (); DisposeWindow (w); */ } return (true); } /*initcolorpopup*/
//----------------------------------------------------------------- //! \brief Display menu at screen position //! \return Pointer to selected Item Desc //----------------------------------------------------------------- void NMenuCtrl::TrackPopupMenu(NPoint _ptScreen, NMenuCtrl* _pParentMenu/*=null*/) { TRACE("NMenuCtrl::TrackPopupMenu\n"); m_dwReturnCmdID = 0; //Calc Menu rect NRect rc; CalcMenuSize(rc); //Move Menu //if (m_pParentWnd) // m_pParentWnd->ClientToScreen(_ptScreen); // Clipping NRect rcApp = GetGUISubSystem()->GetMainWnd()->GetWindowRect(); if(_ptScreen.x + rc.Width() > rcApp.right) _ptScreen.x -= _ptScreen.x + rc.Width() - rcApp.right; if(_ptScreen.y + rc.Height() > rcApp.bottom) _ptScreen.y -= _ptScreen.y + rc.Height() - rcApp.bottom; if (m_pParentWnd) m_pParentWnd->ScreenToClient(_ptScreen); rc.Move(_ptScreen); SetWindowRect(rc); //TRACE("TrackPopupMenu %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom); //TRACE("Count %d\n", m_carrayItems.Count()); //TRACE("_pParentMenu %d\n", _pParentMenu); if (_pParentMenu==null) SetFocus(); //Display menu window ShowMenu(true, _pParentMenu); //Graphic update //Update(); }
/**************************************************************** PopDraw() is the function associated with the user item that invokes the popup menu. We draw the box to look like a menu cell, and then call the appropriate drawProc to fill in the cell with the actual contents. If the drawProc is nil, we draw the menu item as text. We gray the cell if the menu is disabled. Finally, we draw a down arrow to indicate that the button is a popup menu. If the popup item is static, we only draw the cell contents. ****************************************************************/ pascal_ifMac void PopDraw(DialogPtr theDialog, short itemNum) { GrafPtr savePort; short theType; Handle itemHandle; Rect itemBox; Rect cellBox; MenuHandle theMenu; //SysEnvRec theWorld; RGBColor SaveBack, SaveFore, DefaultBack, DefaultFore; char name[256]; short i; short drawStringFlag; // Added by Glen to code for support of Type-in Pop-Up menus // if drawStringFlag = 1 then we don't draw text string ... drawStringFlag = 0; for ( i = 0 ; i < sa_numPopUps ; i++ ) if ( (sa_popTable[i].dialogPtr == theDialog) && (sa_popTable[i].popupItemNum == itemNum) ) break; if (i == sa_numPopUps) { SysBeep(1); return; } // should not happen since the dialog must have been registered // for PopDraw to have been called GetPortGrafPtr(&savePort); SetPortDialogPort(theDialog); // SysEnvirons(curSysEnvVers,&theWorld); // if (theWorld.hasColorQD) { if (ColorQDAvailable()) { GetForeColor(&SaveFore); GetBackColor(&SaveBack); DefaultMenuColors(&DefaultFore, &DefaultBack); if (sa_popTable[i].bStatic) { DefaultFore = SaveFore; DefaultBack = SaveBack; } } theMenu = GetMenuHandle(sa_popTable[i].menuID); if (!theMenu) { SysBeep(1); return; } /* change item's width to match the menu */ GetDialogItem(theDialog,itemNum,&theType,&itemHandle,&itemBox); CalcMenuSize(theMenu); if (sa_popTable[i].itemWidth == 0) { if (sa_popTable[i].drawProc == nil) // itemBox.right = itemBox.left + (**theMenu).menuWidth + 20 + 2; itemBox.right = itemBox.left + GetMenuWidth(theMenu) + 20 + 2; else //itemBox.right = itemBox.left + (**theMenu).menuWidth + 2; itemBox.right = itemBox.left + GetMenuWidth(theMenu) + 2; } else if (sa_popTable[i].itemWidth == -1) { // Type-in Pop-Up Menu itemBox.right = itemBox.left + 20 + 2; drawStringFlag = 1; } else itemBox.right = itemBox.left + sa_popTable[i].itemWidth + 2; SetDialogItem(theDialog,itemNum,theType,itemHandle,&itemBox); /* draw the box */ if (TRUE) { // !sa_popTable[i].bStatic // if (theWorld.hasColorQD) RGBBackColor(&DefaultBack); if (ColorQDAvailable()) RGBBackColor(&DefaultBack); EraseRect( &itemBox ); // if (theWorld.hasColorQD) RGBForeColor(&SaveFore); if (ColorQDAvailable()) RGBForeColor(&SaveFore); PenNormal(); // if (sa_popTable[i].bStatic) PenPat((ConstPatternParam)&qd.gray); //if (sa_popTable[i].bStatic) PenPat((ConstPatternParam)&GRAY_BRUSH()); //if (sa_popTable[i].bStatic) PenPat((ConstPatternParam)&GRAY_BRUSH); if (sa_popTable[i].bStatic) PenPatQDGlobalsGray(); FrameRect(&itemBox); /* draw the shadow */ MoveTo(itemBox.left + 3, itemBox.bottom); Line((itemBox.right - itemBox.left) - 3, 0); Line(0, -((itemBox.bottom - itemBox.top) - 2)); PenNormal(); } else EraseRect( &itemBox ); /* draw the current item in the box */ // if (theWorld.hasColorQD) RGBForeColor(&DefaultFore); if (ColorQDAvailable()) RGBForeColor(&DefaultFore); // Draw text if no Type-in Pop-Up if(drawStringFlag == 0){ if (sa_popTable[i].drawProc != nil) { cellBox = itemBox; InsetRect(&cellBox, 1, 1); (* sa_popTable[i].drawProc) (theMenu, sa_popTable[i].lastItemSelected, &cellBox, // so the drawProc gets the same-size rect, // whether it's drawing in the menu or in the pop-box true, // since we are indeed drawing a pop box item //&theWorld, &DefaultFore, &DefaultBack); } else { MoveTo(itemBox.left + 15, itemBox.top + 4 + (itemBox.bottom - itemBox.top)/2); GetMenuItemText(theMenu, sa_popTable[i].lastItemSelected, (unsigned char *)name); DrawString((unsigned char *)name); } } if (TRUE) { // !sa_popTable[i].bStatic /* cover the item in gray if the menu is disabled */ // if (!((**theMenu).enableFlags & ENABLE_BIT)) { #if TARGET_API_MAC_CARBON Boolean menuIsEnabled = IsMenuItemEnabled(theMenu,0); #else Boolean menuIsEnabled = (**theMenu).enableFlags & ENABLE_BIT; #endif if (!menuIsEnabled) { //PenPat((ConstPatternParam)&qd.gray); //PenPat((ConstPatternParam)&GRAY_BRUSH); PenPatQDGlobalsGray(); PenMode(patOr); //if (theWorld.hasColorQD) RGBForeColor(&DefaultBack); if (ColorQDAvailable()) RGBForeColor(&DefaultBack); else ForeColor(whiteColor); PaintRect(&itemBox); PenNormal(); // if (theWorld.hasColorQD) RGBForeColor(&DefaultFore); if (ColorQDAvailable()) RGBForeColor(&DefaultFore); else ForeColor(blackColor); } /* draw the down arrow */ itemBox.left = itemBox.right - 20; DrawArrow(&itemBox, kDown, sa_popTable[i].bStatic); } //if (theWorld.hasColorQD) { if (ColorQDAvailable()) { RGBForeColor(&SaveFore); RGBBackColor(&SaveBack); } SetPortGrafPort(savePort); }
extern pascal OSStatus InsertSystemSubMenu(MenuRef rootMenu, MenuRef parentMenu, UInt16 itemInParent, MenuRef childMenu) // See comment in interface part. { long oldA4; OSStatus err; SubSysMenuEntry newEntry; SInt16 newIDForChildMenu; oldA4 = SetUpA4(); assert(ValidateSystemMenuRef(rootMenu )); assert(ValidateSystemMenuRef(parentMenu)); assert(ValidateSystemMenuRef(childMenu )); assert(gMenuSelectState = kMenuSelectStatePre); // Validate parameters err = noErr; if ((rootMenu == NULL) || (parentMenu == NULL) || (childMenu == NULL)) { err = paramErr; } if (err == noErr && ((itemInParent == 0) || (itemInParent > CountMenuItems(parentMenu)))) { err = paramErr; } // Make sure rootMenu references a current system menu. // If it does, record the index of the root menu for // later use by HandleMenuSelect. Also fill out the rest // of the fields of the sub-menu entry. if (err == noErr) { newEntry.rootMenuIndex = FindRootMenuByRef(rootMenu); newEntry.parentMenu = parentMenu; newEntry.itemInParent = itemInParent; newEntry.childMenu = childMenu; if (newEntry.rootMenuIndex == kRootMenuNotFound) { err = paramErr; } } // Add newEntry to the sub-menu list, creating the sub-menu list if necessary. if (err == noErr) { if (gSubSysMenus == NULL) { gSubSysMenus = (SubSysMenuHandle) NewHandleSys(0); err = MemError(); } } if (err == noErr) { err = PtrAndHand(&newEntry, (Handle) gSubSysMenus, sizeof(newEntry)); } // Finally, insert the menu with a unique ID into the menu bar, // and set the parent item to reference its ID. if (err == noErr) { newIDForChildMenu = FindUniqueSubMenuID(); (**childMenu).menuID = newIDForChildMenu; InsertMenu(childMenu, hierMenu); SetItemCmd(parentMenu, itemInParent, hMenuCmd); SetItemMark(parentMenu, itemInParent, newIDForChildMenu); // I added this after testing revealed that adding a sub-menu didn't // force the menu size to be recalculated, so the item text of the // hierarchical item in the sub-menu was being truncated. This // only appears to happen on Mac OS 8.5, but the fix is sufficiently // benign to be employed on all systems. CalcMenuSize(parentMenu); } (void) SetA4(oldA4); return err; }