implementation module menuinternal import StdBool, StdList, StdMisc import osmenu, ostypes import iostate, menuaccess, menuitems, sdisize from commondef import fatalError, stateMap, removeCheck, uremove, :: UCond, hdtl from menucreate import disposeMenuIds, disposeShortcutkeys, disposeSubMenuHandles menuinternalFatalError :: String String -> .x menuinternalFatalError function error = fatalError function "menuinternal" error // General rules to access MenuHandles: changeMenuSystemState :: !Bool !(OSMenuBar -> (MenuHandles (PSt .l)) -> *(*OSToolbox -> *(MenuHandles (PSt .l),*OSToolbox))) !(IOSt .l) -> IOSt .l changeMenuSystemState redrawMenus f ioState # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = ioState # (osdinfo,ioState) = ioStGetOSDInfo ioState maybeOSMenuBar = getOSDInfoOSMenuBar osdinfo | isNothing maybeOSMenuBar // This condition should never hold = menuinternalFatalError "changeMenuSystemState" "could not retrieve OSMenuBar from OSDInfo" # osMenuBar = fromJust maybeOSMenuBar # (tb,ioState) = getIOToolbox ioState menus = menuSystemStateGetMenuHandles mDevice # (menus,tb) = f osMenuBar menus tb | not redrawMenus # ioState = setIOToolbox tb ioState = ioStSetDevice (MenuSystemState menus) ioState | otherwise # ioState = setIOToolbox (osDrawMenuBar osMenuBar tb) ioState = ioStSetDevice (MenuSystemState menus) ioState accessMenuSystemState :: !Bool !(OSMenuBar -> u:x -> u:((MenuHandles (PSt .l)) -> u:(*OSToolbox -> *(u:x,MenuHandles (PSt .l),*OSToolbox)))) u:x !(IOSt .l) -> *(u:x,!IOSt .l) accessMenuSystemState redrawMenus f x ioState # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = (x,ioState) # (osdinfo,ioState) = ioStGetOSDInfo ioState maybeOSMenuBar = getOSDInfoOSMenuBar osdinfo | isNothing maybeOSMenuBar // This condition should never hold = menuinternalFatalError "accessMenuSystemState" "could not retrieve OSMenuBar from OSDInfo" # osMenuBar = fromJust maybeOSMenuBar # (tb,ioState) = getIOToolbox ioState menus = menuSystemStateGetMenuHandles mDevice # (x,menus,tb) = f osMenuBar x menus tb | not redrawMenus # ioState = setIOToolbox tb ioState = (x,ioStSetDevice (MenuSystemState menus) ioState) | otherwise # ioState = setIOToolbox (osDrawMenuBar osMenuBar tb) ioState = (x,ioStSetDevice (MenuSystemState menus) ioState) /* Closing a menu. Because in a SDI process menus might reside in the process window, the ViewFrame of the process window can change size. In that case, the layout of the controls should be recalculated, and the window updated. */ closemenu :: !Id !(IOSt .l) -> IOSt .l closemenu id ioState # (osdInfo,ioState) = ioStGetOSDInfo ioState | getOSDInfoDocumentInterface osdInfo==NDI = ioState # maybeOSMenuBar = getOSDInfoOSMenuBar osdInfo | isNothing maybeOSMenuBar = menuinternalFatalError "closemenu" "could not retrieve OSMenuBar from OSDInfo" # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = ioState # mHs = menuSystemStateGetMenuHandles mDevice (menus,mHs) = menuHandlesGetMenus mHs (found,mH,menus) = uremove (isMenuWithThisId id) undef menus | not found = ioStSetDevice (MenuSystemState {mHs & mMenus=menus}) ioState # (menu,mH) = menuStateHandleGetHandle mH (keys,mHs) = menuHandlesGetKeys mHs # (sdiSize1,sdiPtr,ioState) = getSDIWindowSize ioState # (tb,ioState) = getIOToolbox ioState # (mH,(keys,tb)) = filterShortcutkeys osdInfo mH keys tb # (rt,ioState) = ioStGetReceiverTable ioState # (it,ioState) = ioStGetIdTable ioState (_,it) = removeIdFromIdTable id it # (ioid,ioState) = ioStGetIOId ioState (mH,(rt,it)) = closeMenuIds ioid mH (rt,it) # ioState = ioStSetIdTable it ioState # ioState = ioStSetReceiverTable rt ioState # (_,tb) = closeSubMenus mH tb osMenuBar = fromJust maybeOSMenuBar # (osMenuBar,tb) = osMenuRemove menu osMenuBar tb # tb = osDrawMenuBar osMenuBar tb osdInfo = setOSDInfoOSMenuBar osMenuBar osdInfo # ioState = ioStSetOSDInfo osdInfo ioState mHs = {mHs & mMenus=menus,mKeys=keys} # ioState = setIOToolbox tb ioState # ioState = ioStSetDevice (MenuSystemState mHs) ioState # (sdiSize2,_,ioState) = getSDIWindowSize ioState | sdiSize1==sdiSize2 = ioState | otherwise = resizeSDIWindow sdiPtr sdiSize1 sdiSize2 ioState where isMenuWithThisId :: !Id !(MenuStateHandle .pst) -> *(!Bool,!MenuStateHandle .pst) isMenuWithThisId id msH # (menuId,msH) = menuStateHandleGetMenuId msH = (id==menuId,msH) closeSubMenus :: !(MenuStateHandle .pst) !*OSToolbox -> (!MenuStateHandle .pst,!*OSToolbox) closeSubMenus (MenuLSHandle mH=:{mlsHandle=mlsH=:{mHandle=mParentH,mItems=itemHs}}) tb # (itemHs,(_,tb)) = stateMap disposeSubMenuHandles itemHs (mParentH,tb) = (MenuLSHandle {mH & mlsHandle={mlsH & mItems=itemHs}},tb) closeMenuIds :: !SystemId !(MenuStateHandle .pst) !*(!*ReceiverTable,!*IdTable) -> (!MenuStateHandle .pst,!*(!*ReceiverTable,!*IdTable)) closeMenuIds pid (MenuLSHandle mH=:{mlsHandle=mlsH=:{mItems=itemHs}}) (rt,it) # (itemHs,ts) = stateMap (disposeMenuIds pid) itemHs (rt,it) = (MenuLSHandle {mH & mlsHandle={mlsH & mItems=itemHs}},ts) filterShortcutkeys :: !OSDInfo !(MenuStateHandle .pst) ![Char] !*OSToolbox -> (!MenuStateHandle .pst,!(![Char],!*OSToolbox)) filterShortcutkeys osdInfo (MenuLSHandle mH=:{mlsHandle=mlsH=:{mItems=itemHs}}) keys tb # (itemHs,keys_tb) = stateMap (disposeShortcutkeys framePtr) itemHs (keys,tb) = (MenuLSHandle {mH & mlsHandle={mlsH & mItems=itemHs}},keys_tb) where framePtr = case (getOSDInfoOSInfo osdInfo) of Just info -> info.osFrame _ -> OSNoWindowPtr // Enabling and Disabling of Menus: enablemenus :: ![Id] !(IOSt .l) -> IOSt .l enablemenus ids ioState = changeMenuSystemState True (setSelectMenus ids Able) ioState disablemenus :: ![Id] !(IOSt .l) -> IOSt .l disablemenus ids ioState = changeMenuSystemState True (setSelectMenus ids Unable) ioState setSelectMenus :: ![Id] !SelectState !OSMenuBar !(MenuHandles .pst) !*OSToolbox -> (!MenuHandles .pst,!*OSToolbox) setSelectMenus ids select osMenuBar menus=:{mEnabled,mMenus} tb # (_,msHs,tb) = setSelectMenuHandles 0 select osMenuBar mEnabled ids mMenus tb = ({menus & mMenus=msHs},tb) where setSelectMenuHandles :: !Int !SelectState !OSMenuBar !Bool ![Id] !*[MenuStateHandle .ps] !*OSToolbox -> (![Id],!*[MenuStateHandle .ps],!*OSToolbox) setSelectMenuHandles _ _ _ _ ids [] tb = (ids,[],tb) setSelectMenuHandles zIndex select osMenuBar systemAble ids [msH:msHs] tb | isEmpty ids = (ids,[msH:msHs],tb) | otherwise # (ids,msH, tb) = setSelectMenuHandle zIndex select osMenuBar systemAble ids msH tb # (ids,msHs,tb) = setSelectMenuHandles (zIndex+1) select osMenuBar systemAble ids msHs tb = (ids,[msH:msHs],tb) where setSelectMenuHandle :: !Int !SelectState !OSMenuBar !Bool ![Id] !(MenuStateHandle .ps) !*OSToolbox -> (![Id], !MenuStateHandle .ps, !*OSToolbox) setSelectMenuHandle zIndex select osMenuBar systemAble ids msH=:(MenuLSHandle mlsH=:{mlsHandle=mH=:{mMenuId}}) tb # (containsId,ids) = removeCheck mMenuId ids | not containsId = (ids,msH,tb) # msH = MenuLSHandle {mlsH & mlsHandle={mH & mSelect=enabled select}} | not systemAble = (ids,msH,tb) | enabled select = (ids,msH,osEnableMenu zIndex osMenuBar tb) | otherwise = (ids,msH,osDisableMenu zIndex osMenuBar tb) // Removing menu elements from (sub/radio)menus: closemenuelements :: !Id ![Id] !(IOSt .l) -> IOSt .l closemenuelements mId ids ioState # (pid,ioState) = ioStGetIOId ioState # (rt,ioState) = ioStGetReceiverTable ioState # (it,ioState) = ioStGetIdTable ioState # (osdInfo,ioState) = ioStGetOSDInfo ioState # ((rt,it),ioState) = accessMenuSystemState True (removeMenusItems osdInfo mId ids pid) (rt,it) ioState # ioState = ioStSetIdTable it ioState # ioState = ioStSetReceiverTable rt ioState = ioState // Removing menu elements from (sub/radio)menus by index (counting from 1): RemoveSpecialMenuElements :== True // For closemenuindexelements: remove elements with special ids NotRemoveSpecialMenuElements:== False // For closemenuindexelements: do not remove elements with special ids closemenuindexelements :: !Bool !Bool !SystemId !(!Id,!Maybe Id) ![Index] !(IOSt .l) -> IOSt .l closemenuindexelements removeSpecialElements fromRadioMenu pid loc indices ioState # (rt,ioState) = ioStGetReceiverTable ioState # (it,ioState) = ioStGetIdTable ioState # (osdInfo,ioState) = ioStGetOSDInfo ioState # ((rt,it),ioState) = accessMenuSystemState True (removeMenusIndexItems osdInfo removeSpecialElements fromRadioMenu loc indices pid) (rt,it) ioState # ioState = ioStSetIdTable it ioState # ioState = ioStSetReceiverTable rt ioState = ioState // Set & Get the title of a menu. setmenutitle :: !Id !Title !(IOSt .l) -> IOSt .l setmenutitle id title ioState = changeMenuSystemState True (setOSMenuTitle id title) ioState where setOSMenuTitle :: !Id !Title !OSMenuBar !(MenuHandles .pst) !*OSToolbox -> (!MenuHandles .pst,!*OSToolbox) setOSMenuTitle id title osMenuBar menus=:{mMenus} tb # (msHs,tb) = setOSMenusTitle id title osMenuBar mMenus tb = ({menus & mMenus=msHs},tb) where setOSMenusTitle :: !Id !Title !OSMenuBar ![MenuStateHandle .pst] !*OSToolbox -> (![MenuStateHandle .pst],!*OSToolbox) setOSMenusTitle id title osMenuBar [msH:msHs] tb # (menuId,msH) = menuStateHandleGetMenuId msH | id==menuId # (mH,msH) = menuStateHandleGetHandle msH msH = menuStateHandleSetTitle title msH # tb = osChangeMenuTitle osMenuBar mH title tb = ([msH:msHs],tb) | otherwise # (msHs,tb) = setOSMenusTitle id title osMenuBar msHs tb = ([msH:msHs],tb) setOSMenusTitle _ _ _ [] tb = ([],tb)