implementation module StdMenu import StdBool, StdList, StdTuple import osmenu import commondef, iostate, menuaccess, menucreate, menudevice, menuevent, menuinternal, menuitems, StdId from devicesystemstate import windowSystemStateGetWindowHandles from menudefaccess import menuDefGetMenuId from devicesystemstate import menuSystemStateGetMenuHandles from StdPSt import accPIO from windowaccess import getWindowHandlesActiveModalDialog stdMenuFatalError :: String String -> .x stdMenuFatalError function error = fatalError function "StdMenu" error // General rules to access MenuHandles: accessMenuHandles :: !Id !((MenuStateHandle (PSt .l)) -> (x,!MenuStateHandle (PSt .l))) !(IOSt .l) -> (!Maybe x,!IOSt .l) accessMenuHandles id f ioState # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = (Nothing,ioState) # mHs = menuSystemStateGetMenuHandles mDevice (result,msHs) = accessmenuhandles id f mHs.mMenus # ioState = ioStSetDevice (MenuSystemState {mHs & mMenus=msHs}) ioState = (result,ioState) where accessmenuhandles :: !Id !((MenuStateHandle .pst) -> (x,!MenuStateHandle .pst)) ![MenuStateHandle .pst] -> (!Maybe x,![MenuStateHandle .pst]) accessmenuhandles id f [mH:mHs] # (menu_id,mH) = menuStateHandleGetMenuId mH | id==menu_id # (result,mH) = f mH = (Just result,[mH:mHs]) | otherwise # (opt_result,mHs) = accessmenuhandles id f mHs = (opt_result,[mH:mHs]) accessmenuhandles _ _ _ = (Nothing,[]) changeMenuSystemState :: !Bool !(OSMenuBar -> (MenuHandles (PSt .l)) -> *(*OSToolbox -> *(MenuHandles (PSt .l),*OSToolbox))) !(IOSt .l) -> IOSt .l changeMenuSystemState redrawMenus f ioState # (osdInfo,ioState) = ioStGetOSDInfo ioState maybeOSMenuBar = getOSDInfoOSMenuBar osdInfo | isNothing maybeOSMenuBar // This condition should never hold = stdMenuFatalError "changeMenuSystemState" "could not retrieve OSMenuBar from IOSt" # osMenuBar = fromJust maybeOSMenuBar # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = ioState # (tb,ioState) = getIOToolbox ioState menus = menuSystemStateGetMenuHandles mDevice # (menus,tb) = f osMenuBar menus tb | not redrawMenus # ioState = setIOToolbox tb ioState = ioStSetDevice (MenuSystemState menus) ioState | otherwise # tb = osDrawMenuBar osMenuBar tb osdInfo = setOSDInfoOSMenuBar osMenuBar osdInfo # ioState = ioStSetOSDInfo osdInfo ioState # ioState = setIOToolbox tb ioState = ioStSetDevice (MenuSystemState menus) ioState accessMenuSystemState :: !Bool !(OSMenuBar -> (MenuHandles (PSt .l)) -> *(*OSToolbox -> *(.x,MenuHandles (PSt .l),*OSToolbox))) !(IOSt .l) -> (!Maybe .x,!IOSt .l) accessMenuSystemState redrawMenus f ioState # (osdInfo,ioState) = ioStGetOSDInfo ioState maybeOSMenuBar = getOSDInfoOSMenuBar osdInfo | isNothing maybeOSMenuBar // This condition should never hold = stdMenuFatalError "accessMenuSystemState" "could not retrieve OSMenuBar from IOSt" # osMenuBar = fromJust maybeOSMenuBar # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = (Nothing,ioState) # (tb,ioState) = getIOToolbox ioState menus = menuSystemStateGetMenuHandles mDevice # (x,menus,tb) = f osMenuBar menus tb | not redrawMenus # ioState = setIOToolbox tb ioState = (Just x,ioStSetDevice (MenuSystemState menus) ioState) | otherwise # tb = osDrawMenuBar osMenuBar tb osdInfo = setOSDInfoOSMenuBar osMenuBar osdInfo # ioState = ioStSetOSDInfo osdInfo ioState # ioState = setIOToolbox tb ioState = (Just x,ioStSetDevice (MenuSystemState menus) ioState) // Opening a menu for an interactive process. class Menus mdef where openMenu :: .ls !.(mdef .ls (PSt .l)) !(PSt .l) -> (!ErrorReport,!PSt .l) getMenuType :: .(mdef .ls .pst) -> MenuType instance Menus (Menu m) | MenuElements m where openMenu ls mDef pState # pState = menuFunctions.dOpen pState # (isZero,pState) = accPIO checkZeroMenuBound pState | isZero = (ErrorViolateDI,pState) # (optMenuId,mDef) = menuDefGetMenuId mDef # (optMenuId,pState)= accPIO (validateMenuId optMenuId) pState | isNothing optMenuId = (ErrorIdsInUse,pState) # menuId = fromJust optMenuId | menuId==windowMenuId = (ErrorIdsInUse,pState) | otherwise = openMenu` menuId ls mDef pState where checkZeroMenuBound :: !(IOSt .l) -> (!Bool,!IOSt .l) checkZeroMenuBound ioState # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found // This condition should never occur = stdMenuFatalError "openMenu (Menu)" "could not retrieve MenuSystemState from IOSt" # mHs = menuSystemStateGetMenuHandles mDevice (bound,mHs) = (\msHs=:{mNrMenuBound}->(mNrMenuBound,msHs)) mHs # ioState = ioStSetDevice (MenuSystemState mHs) ioState = (zeroBound bound,ioState) getMenuType _ = "Menu" validateMenuId :: !(Maybe Id) !(IOSt .l) -> (!Maybe Id,!IOSt .l) validateMenuId Nothing ioState # (mId,ioState) = openId ioState = (Just mId,ioState) validateMenuId (Just id) ioState # (idtable,ioState) = ioStGetIdTable ioState # (member,idtable) = memberIdTable id idtable | member = (Nothing,ioStSetIdTable idtable ioState) | otherwise = (Just id,ioStSetIdTable idtable ioState) instance Menus (PopUpMenu m) | PopUpMenuElements m where openMenu ls mDef pState # (osdInfo,pState) = accPIO ioStGetOSDInfo pState | getOSDInfoDocumentInterface osdInfo==NDI = (ErrorViolateDI,pState) # maybeOSMenuBar = getOSDInfoOSMenuBar osdInfo | isNothing maybeOSMenuBar // This condition should never occur = stdMenuFatalError "openMenu (PopUpMen)" "OSMenuBar could not be retrieved from OSDInfo" # pState = menuFunctions.dOpen pState # (found,mDevice,ioState) = ioStGetDevice MenuDevice pState.io | not found = (ErrorUnknownObject,{pState & io=ioState}) # mHs = menuSystemStateGetMenuHandles mDevice mHs = closepopupmenu mHs osMenuBar = fromJust maybeOSMenuBar # (idtable,ioState) = ioStGetIdTable ioState # (rt,ioState) = ioStGetReceiverTable ioState # (ioid,ioState) = ioStGetIOId ioState # (ok,mHs,rt,idtable,osMenuBar,pState) = createPopUpMenu ioid ls mDef mHs rt idtable osMenuBar {pState & io=ioState} osdInfo = setOSDInfoOSMenuBar osMenuBar osdInfo # ioState = ioStSetOSDInfo osdInfo pState.io # ioState = ioStSetReceiverTable rt ioState # ioState = ioStSetIdTable idtable ioState # ioState = ioStSetDevice (MenuSystemState mHs) ioState # pState = {pState & io=ioState} | ok = (NoError,handlePopUpMenu pState) | otherwise = (ErrorIdsInUse,pState) where // handlePopUpMenu opens the pop up menu. /* handlePopUpMenu :: !(PSt .l) -> (!ErrorReport,!PSt .l) handlePopUpMenu pState # (osdInfo,ioState) = ioStGetOSDInfo pState.io framePtr = case (getOSDInfoOSInfo osdInfo) of Just info -> info.osFrame nothing -> stdMenuFatalError "openMenu (PopUpMenu)" "incorrect OSDInfo retrieved" # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found // This condition should never occur = stdMenuFatalError "openMenu (PopUpMenu)" "could not retrieve MenuSystemState from IOSt" # mHs = menuSystemStateGetMenuHandles mDevice (menus,mHs) = menuHandlesGetMenus mHs (popUpMenu,menus) = hdtl menus (popUpId,popUpMenu) = menuStateHandleGetMenuId popUpMenu (mPtr,popUpMenu) = menuStateHandleGetHandle popUpMenu // # ((ok,event,popUpMenu),ioState) = accIOToolbox (osTrackPopUpMenu mPtr framePtr popUpMenu) ioState # ((itemNr,menuMods),ioState) = accIOToolbox (osTrackPopUpMenu mPtr framePtr) ioState # ((ok,event,popUpMenu),ioState) = case itemNr of 0 -> ((True,Nothing,popUpMenu),ioState) _ -> accIOToolbox (getSelectedMenuStateHandleItem itemNr menuMods popUpMenu) ioState | not ok # ioState = ioStSetDevice (MenuSystemState {mHs & mMenus=menus,mPopUpId=Just popUpId}) ioState # pState = {pState & io=ioState} = (OtherError "PopUpMenu tracking error",pState) | otherwise # ioState = ioStSetDevice (MenuSystemState {mHs & mMenus=[popUpMenu:menus]}) ioState # pState = {pState & io=ioState} = (NoError,pState) */ handlePopUpMenu :: !(PSt .ps) -> PSt .ps handlePopUpMenu pState # (osdInfo,ioState) = ioStGetOSDInfo pState.io framePtr = case (getOSDInfoOSInfo osdInfo) of Just info -> info.osFrame nothing -> stdMenuFatalError "openMenu (PopUpMenu)" "incorrect OSDInfo retrieved" # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found // This condition should never occur = stdMenuFatalError "openMenu (PopUpMenu)" "could not retrieve MenuSystemState from IOSt" # (tb,ioState) = getIOToolbox ioState mHs = menuSystemStateGetMenuHandles mDevice (menus,mHs) = menuHandlesGetMenus mHs (popUpMenu,menus) = hdtl menus // (popUpId,popUpMenu) = menuStateHandleGetMenuId popUpMenu PA: not needed anymore (mPtr,popUpMenu) = menuStateHandleGetHandle popUpMenu # (maybePopUpItem,tb) = osTrackPopUpMenu mPtr framePtr tb | isNothing maybePopUpItem // No item has been selected # ioState = setIOToolbox tb ioState # ioState = ioStSetDevice (MenuSystemState {mHs & mMenus=[popUpMenu:menus]}) ioState # pState = {pState & io=ioState} = pState # (maybePopUpEvent,popUpMenu,tb)= popUpMenuEvent (fromJust maybePopUpItem) popUpMenu tb # ioState = setIOToolbox tb ioState # ioState = ioStSetDevice (MenuSystemState {mHs & mMenus=[popUpMenu:menus]}) ioState # pState = {pState & io=ioState} | isNothing maybePopUpEvent // No abstract event is associated with the item = pState | otherwise // Evaluate the abstract event = snd (menuFunctions.dDoIO (fromJust maybePopUpEvent) pState) getMenuType _ = "PopUpMenu" /* PA: no need to copy/adapt code. Better to reuse menuevent and menudevice. // where (copied from ?menuevent) getSelectedMenuStateHandleItem :: !Int !Modifiers !(MenuStateHandle .pst) !*OSToolbox -> ((!Bool,!Maybe DeviceEvent,!MenuStateHandle .pst), !*OSToolbox) getSelectedMenuStateHandleItem itemNr mods msH=:(MenuLSHandle mlsH=:{mlsHandle=mH=:{mSelect,mHandle,mMenuId,mItems,mOSMenuNr}}) tb | not mSelect = ((False,Nothing,msH),tb) | otherwise # (found,menuEvent,_,_,itemHs,tb) = getSelectedMenuElementHandlesItem itemNr mHandle mMenuId mOSMenuNr mods [] 1 mItems tb = ((found,menuEvent,MenuLSHandle {mlsH & mlsHandle={mH & mItems=itemHs}}),tb) where getSelectedMenuElementHandlesItem :: !Int !OSMenu !Id !OSMenuNr !Modifiers ![Int] !Int ![MenuElementHandle .ls .pst] !*OSToolbox -> (!Bool,!Maybe DeviceEvent,![Int],!Int,![MenuElementHandle .ls .pst],!*OSToolbox) getSelectedMenuElementHandlesItem itemNr mH mMenuId mOSMenuNr mods parents zIndex itemHs tb # (isEmpty,itemHs) = uisEmpty itemHs | isEmpty = (False,Nothing,parents,zIndex,itemHs,tb) # (itemH,itemHs) = hdtl itemHs # (found,menuEvent,parents,zIndex,itemH,tb) = getSelectedMenuElementHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex itemH tb | found = (found,menuEvent,parents,zIndex,[itemH:itemHs],tb) | otherwise # (found,menuEvent,parents,zIndex,itemHs,tb)= getSelectedMenuElementHandlesItem itemNr mH mMenuId mOSMenuNr mods parents zIndex itemHs tb = (found,menuEvent,parents,zIndex,[itemH:itemHs],tb) where getSelectedMenuElementHandle :: !Int !OSMenu !Id !OSMenuNr !Modifiers ![Int] !Int !(MenuElementHandle .ls .pst) !*OSToolbox -> (!Bool,!Maybe DeviceEvent,![Int],!Int, !MenuElementHandle .ls .pst, !*OSToolbox) getSelectedMenuElementHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex itemH=:(MenuItemHandle {mOSMenuItem,mItemId}) tb // # tb = trace_n ("?: z"+++toString zIndex+++" mOSM: "+++toString mOSMenuNr) tb | itemNr==zIndex // #! tb = trace_n (zIndex,pretty parents) tb = (True,Just (MenuTraceEvent {mtId=mMenuId,mtParents=parents,mtItemNr=itemNr-1,mtModifiers= mods}),parents,zIndex+1,itemH,tb) | otherwise = (False,Nothing,parents,zIndex+1,itemH,tb) /* getSelectedMenuElenebtHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex itemH=:(MenuSeparatorHandle) tb | itemNr == zIndex = () | otherwise = (False,Nothing,parents,zIndex+1,itemH,tb) */ getSelectedMenuElementHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex itemH=:(SubMenuHandle submenuH=:{mSubOSMenuNr,mSubSelect,mSubHandle,mSubItems}) tb // #! tb = trace_n ("mSubOSMenuNr",mSubOSMenuNr,zIndex) tb | not mSubSelect = (False,Nothing,parents,zIndex+1,itemH,tb) | otherwise #! parents1 = parents++[zIndex-1] // #! tb = trace_n ("parents1 before ",pretty parents1) tb # (found,menuEvent,parents1,_,itemHs,tb) = getSelectedMenuElementHandlesItem itemNr mSubHandle mMenuId mSubOSMenuNr mods parents1 1 mSubItems tb // #! tb = trace_n ("parents1 after",pretty parents1,found) tb # itemH = SubMenuHandle {submenuH & mSubItems=itemHs} parents = if found parents1 parents = (found,menuEvent,parents,zIndex+1,itemH,tb) getSelectedMenuElementHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex (RadioMenuHandle rH=:{mRadioSelect,mRadioItems=itemHs,mRadioIndex}) tb # (nrRadios,itemHs) = ulength itemHs | not mRadioSelect = (False,Nothing,parents,zIndex+nrRadios,RadioMenuHandle {rH & mRadioItems=itemHs},tb) // # (found,menuEvent,parents,zIndex1,itemHs,tb) = getSelectedMenuElementHandlesItem itemNr mH mMenuId mods parents zIndex itemHs tb// itemNr mH mMenuId mmods parents zIndex itemHs tb # (found,menuEvent,parents,zIndex1,itemHs,tb) = getSelectedMenuElementHandlesItem itemNr mH mMenuId mOSMenuNr mods parents zIndex itemHs tb | not found = (found,menuEvent,parents,zIndex1,RadioMenuHandle {rH & mRadioItems=itemHs},tb) # curIndex = mRadioIndex newIndex = zIndex1-zIndex | curIndex==newIndex = (found,menuEvent,parents,zIndex1,RadioMenuHandle {rH & mRadioItems=itemHs},tb) | otherwise # (before,[itemH:after])= splitAt (curIndex-1) itemHs # (curH,itemH) = getMenuItemOSMenuItem itemH # (before,[itemH:after])= splitAt (newIndex-1) (before ++ [itemH:after]) # (newH,itemH) = getMenuItemOSMenuItem itemH # tb = osMenuItemCheck False mH curH curIndex (curIndex+zIndex-1) tb # tb = osMenuItemCheck True mH newH newIndex (zIndex1-1) tb = (found,menuEvent,parents,zIndex1,RadioMenuHandle {rH & mRadioItems=before ++ [itemH:after],mRadioIndex=newIndex},tb) where getMenuItemOSMenuItem :: !*(MenuElementHandle .ls .pst) -> (!OSMenuItem,!MenuElementHandle .ls .pst) getMenuItemOSMenuItem itemH=:(MenuItemHandle {mOSMenuItem}) = (mOSMenuItem,itemH) getSelectedMenuElementHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex (MenuListLSHandle itemHs) tb # (found,menuEvent,parents,zIndex,itemHs,tb) = getSelectedMenuElementHandlesItem itemNr mH mMenuId mOSMenuNr mods parents zIndex itemHs tb = (found,menuEvent,parents,zIndex,MenuListLSHandle itemHs,tb) getSelectedMenuElementHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex (MenuExtendLSHandle mExH=:{mExtendItems=itemHs}) tb # (found,menuEvent,parents,zIndex,itemHs,tb) = getSelectedMenuElementHandlesItem itemNr mH mMenuId mOSMenuNr mods parents zIndex itemHs tb = (found,menuEvent,parents,zIndex,MenuExtendLSHandle {mExH & mExtendItems=itemHs},tb) getSelectedMenuElementHandle itemNr mH mMenuId mOSMenuNr mods parents zIndex (MenuChangeLSHandle mChH=:{mChangeItems=itemHs}) tb # (found,menuEvent,parents,zIndex,itemHs,tb) = getSelectedMenuElementHandlesItem itemNr mH mMenuId mOSMenuNr mods parents zIndex itemHs tb = (found,menuEvent,parents,zIndex,MenuChangeLSHandle {mChH & mChangeItems=itemHs},tb) getSelectedMenuElementHandle _ _ _ _ _ parents zIndex itemH=:(MenuReceiverHandle _) tb = (False,Nothing,parents,zIndex,itemH,tb) getSelectedMenuElementHandle _ _ _ _ _ parents zIndex itemH tb = (False,Nothing,parents,zIndex+1,itemH,tb) */ // Closing a menu. closeMenu :: !Id !(IOSt .l) -> IOSt .l closeMenu id ioState | id==windowMenuId = ioState | otherwise = closemenu id ioState // Enabling and Disabling of the MenuSystem: enableMenuSystem :: !(IOSt .l) -> IOSt .l enableMenuSystem ioState # (isModal,ioState) = hasModalDialog ioState | isModal = ioState # (di,ioState) = ioStGetDocumentInterface ioState | di==NDI = ioState | otherwise = changeMenuSystemState True (enablemenusystem di) ioState where hasModalDialog :: !(IOSt .l) -> (!Bool,!IOSt .l) hasModalDialog ioState # (found,wDevice,ioState) = ioStGetDevice WindowDevice ioState | not found = (False,ioState) | otherwise # windows = windowSystemStateGetWindowHandles wDevice (modalWIDS,windows) = getWindowHandlesActiveModalDialog windows # ioState = ioStSetDevice (WindowSystemState windows) ioState = (isJust modalWIDS,ioState) enablemenusystem :: !DocumentInterface !OSMenuBar !(MenuHandles .pst) !*OSToolbox -> (!MenuHandles .pst,!*OSToolbox) enablemenusystem di osMenuBar menus=:{mEnabled,mMenus} tb | mEnabled = (menus,tb) | otherwise # (nrMenus,msHs)= ulength mMenus // # tb = enablemenus (if (di==MDI) (nrMenus+1) (nrMenus-1)) osMenuBar tb # tb = enablemenus nrMenus osMenuBar tb = ({menus & mMenus=msHs,mEnabled=SystemAble},tb) where enablemenus :: !Int !OSMenuBar !*OSToolbox -> *OSToolbox enablemenus i osmenubar tb | i<0 = tb | otherwise = enablemenus (i-1) osMenuBar (osEnableMenu i osMenuBar tb) disableMenuSystem :: !(IOSt .l) -> IOSt .l disableMenuSystem ioState # (di,ioState) = ioStGetDocumentInterface ioState | di==NDI = ioState | otherwise = changeMenuSystemState True (disablemenusystem di) ioState where disablemenusystem :: !DocumentInterface !OSMenuBar !(MenuHandles .pst) !*OSToolbox -> (!MenuHandles .pst,!*OSToolbox) disablemenusystem di osMenuBar menus=:{mEnabled,mMenus} tb | not mEnabled = (menus,tb) | otherwise # (nrMenus,msHs)= ulength mMenus // # tb = disablemenus (if (di==MDI) (nrMenus+1) (nrMenus-1)) osMenuBar tb # tb = disablemenus nrMenus osMenuBar tb // DvA: zou MDI (en SDI/NDI?) geval nu niet gewoon nrMenus moeten zijn? = ({menus & mMenus=msHs,mEnabled=SystemUnable},tb) where disablemenus :: !Int !OSMenuBar !*OSToolbox -> *OSToolbox disablemenus i osMenuBar tb | i<0 = tb | otherwise = disablemenus (i-1) osMenuBar (osDisableMenu i osMenuBar tb) // Enabling and Disabling of Menus: enableMenus :: ![Id] !(IOSt .l) -> IOSt .l enableMenus ids ioState # ids = filter ((<>) windowMenuId) ids | isEmpty ids = ioState | otherwise = enablemenus ids ioState disableMenus :: ![Id] !(IOSt .l) -> IOSt .l disableMenus ids ioState # ids = filter ((<>) windowMenuId) ids | isEmpty ids = ioState | otherwise = disablemenus ids ioState // Get the SelectState of a menu: getMenuSelectState :: !Id !(IOSt .l) -> (!Maybe SelectState,!IOSt .l) getMenuSelectState id ioState # (optSelect,ioState) = accessMenuHandles id menuStateHandleGetSelect ioState | isNothing optSelect = (Nothing, ioState) | fromJust optSelect = (Just Able, ioState) | otherwise = (Just Unable, ioState) /* Adding menu elements to (sub/radio)menus: Items in a (sub/radio)menu are positioned starting from 1 and increasing by 1. Open with a position less than 1 adds the new elements in front Open with a position higher than the number of items adds the new elements to the end. Open an item on a position adds the item AFTER the item on that position. */ openMenuElements :: !Id !Index .ls .(m .ls (PSt .l)) !(PSt .l) -> (!ErrorReport,!PSt .l) | MenuElements m openMenuElements mId pos ls new pState # (it,ioState) = ioStGetIdTable pState.io # (maybeParent,it) = getIdParent mId it | isNothing maybeParent = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # parent = fromJust maybeParent | parent.idpDevice<>MenuDevice = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # (pid,ioState) = ioStGetIOId ioState | parent.idpIOId<>pid = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) | parent.idpId<>mId = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # (osdInfo,ioState) = ioStGetOSDInfo ioState maybeOSMenuBar = getOSDInfoOSMenuBar osdInfo | isNothing maybeOSMenuBar // This condition should not occur = stdMenuFatalError "openMenuElements" "OSMenuBar could not be retrieved from OSDInfo" | otherwise # osMenuBar = fromJust maybeOSMenuBar # (rt, ioState) = ioStGetReceiverTable ioState # (tb, ioState) = getIOToolbox ioState # pState = {pState & io=ioState} menus = menuSystemStateGetMenuHandles mDevice # ((error,rt,it),menus,osMenuBar,pState) = addMenusItems (mId,Nothing) (max 0 pos) ls new pid rt it menus osMenuBar pState # ioState = setIOToolbox (osDrawMenuBar osMenuBar tb) pState.io mDevice = MenuSystemState menus osdInfo = setOSDInfoOSMenuBar osMenuBar osdInfo # ioState = ioStSetOSDInfo osdInfo ioState # ioState = ioStSetDevice mDevice ioState # ioState = ioStSetIdTable it ioState # ioState = ioStSetReceiverTable rt ioState # pState = {pState & io=ioState} = (error,pState) openSubMenuElements :: !Id !Index .ls .(m .ls (PSt .l)) !(PSt .l) -> (!ErrorReport,!PSt .l) | MenuElements m openSubMenuElements sId pos ls new pState # (it,ioState) = ioStGetIdTable pState.io # (maybeParent,it) = getIdParent sId it | isNothing maybeParent = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # parent = fromJust maybeParent | parent.idpDevice<>MenuDevice = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # (pid,ioState) = ioStGetIOId ioState | parent.idpIOId<>pid = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = (ErrorUnknownObject,{pState & io=ioStSetIdTable it ioState}) # (osdInfo,ioState) = ioStGetOSDInfo ioState maybeOSMenuBar = getOSDInfoOSMenuBar osdInfo | isNothing maybeOSMenuBar // This condition should not occur = stdMenuFatalError "openSubMenuElements" "OSMenuBar could not be retrieved from OSDInfo" | otherwise # osMenuBar = fromJust maybeOSMenuBar # (rt,ioState) = ioStGetReceiverTable ioState # (tb,ioState) = getIOToolbox ioState # pState = {pState & io=ioState} menus = menuSystemStateGetMenuHandles mDevice # ((error,rt,it),menus,osMenuBar,pState) = addMenusItems (parent.idpId,Just sId) (max 0 pos) ls new pid rt it menus osMenuBar pState # ioState = setIOToolbox (osDrawMenuBar osMenuBar tb) pState.io mDevice = MenuSystemState menus osdInfo = setOSDInfoOSMenuBar osMenuBar osdInfo # ioState = ioStSetOSDInfo osdInfo ioState # ioState = ioStSetDevice mDevice ioState # ioState = ioStSetIdTable it ioState # ioState = ioStSetReceiverTable rt ioState # pState = {pState & io=ioState} = (error,pState) openRadioMenuItems :: !Id !Index ![MenuRadioItem (PSt .l)] !(IOSt .l) -> (!ErrorReport,!IOSt .l) openRadioMenuItems rId pos radioItems ioState # (idtable,ioState) = ioStGetIdTable ioState # (maybeParent,idtable) = getIdParent rId idtable | isNothing maybeParent = (ErrorUnknownObject,ioStSetIdTable idtable ioState) # parent = fromJust maybeParent | parent.idpDevice<>MenuDevice = (ErrorUnknownObject,ioStSetIdTable idtable ioState) # (ioId,ioState) = ioStGetIOId ioState | parent.idpIOId<>ioId = (ErrorUnknownObject,ioStSetIdTable idtable ioState) | isEmpty radioItems = (NoError,ioStSetIdTable idtable ioState) # radioIds = filterMap (\(_,maybeId,_,_)->(isJust maybeId,fromJust maybeId)) radioItems # (ok,idtable) = okMembersIdTable radioIds idtable | not ok = (ErrorIdsInUse,ioStSetIdTable idtable ioState) | otherwise # mId = parent.idpId # (error,ioState) = accessMenuSystemState True (addMenuRadioItems (mId,rId) (max 0 pos) radioItems) ioState # ioState = ioStSetIdTable (snd (addIdsToIdTable (map (\id->(id,{idpIOId=ioId,idpDevice=MenuDevice,idpId=mId})) radioIds) idtable)) ioState error = case error of Nothing -> ErrorUnknownObject Just err -> err = (error,ioState) // Removing menu elements from (sub/radio)menus: closeMenuElements :: !Id ![Id] !(IOSt .l) -> IOSt .l closeMenuElements mId ids ioState # ids = filter (\id->not (isSpecialId id)) ids | isEmpty ids = ioState | otherwise = closemenuelements mId ids ioState // Removing menu elements from (sub/radio)menus by index (counting from 1): closeMenuIndexElements :: !Id ![Index] !(IOSt .l) -> IOSt .l closeMenuIndexElements mId indices ioState # (idtable,ioState) = ioStGetIdTable ioState # (maybeParent,idtable) = getIdParent mId idtable # ioState = ioStSetIdTable idtable ioState | isNothing maybeParent = ioState # parent = fromJust maybeParent | parent.idpDevice<>MenuDevice = ioState # (ioId,ioState) = ioStGetIOId ioState | parent.idpIOId<>ioId || parent.idpId<>mId = ioState | otherwise = closemenuindexelements NotRemoveSpecialMenuElements False ioId (mId,Nothing) indices ioState closeSubMenuIndexElements :: !Id ![Index] !(IOSt .l) -> IOSt .l closeSubMenuIndexElements sId indices ioState # (idtable,ioState) = ioStGetIdTable ioState # (maybeParent,idtable) = getIdParent sId idtable # ioState = ioStSetIdTable idtable ioState | isNothing maybeParent = ioState # parent = fromJust maybeParent | parent.idpDevice<>MenuDevice = ioState # (ioId,ioState) = ioStGetIOId ioState | parent.idpIOId<>ioId = ioState | otherwise = closemenuindexelements NotRemoveSpecialMenuElements False ioId (parent.idpId,Just sId) indices ioState closeRadioMenuIndexElements :: !Id ![Index] !(IOSt .l) -> IOSt .l closeRadioMenuIndexElements rId indices ioState # (idtable,ioState) = ioStGetIdTable ioState # (maybeParent,idtable) = getIdParent rId idtable # ioState = ioStSetIdTable idtable ioState | isNothing maybeParent = ioState # parent = fromJust maybeParent | parent.idpDevice<>MenuDevice = ioState # (ioId,ioState) = ioStGetIOId ioState | parent.idpIOId<>ioId = ioState | otherwise = closemenuindexelements NotRemoveSpecialMenuElements True ioId (parent.idpId,Just rId) indices ioState // Determine the Ids and MenuTypes of all menus. getMenus :: !(IOSt .l) -> (![(Id,MenuType)],!IOSt .l) getMenus ioState # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = ([],ioState) | otherwise # mHs = menuSystemStateGetMenuHandles mDevice (idtypes,msHs) = accessList getIdType mHs.mMenus # ioState = ioStSetDevice (MenuSystemState {mHs & mMenus=msHs}) ioState = (/*tl*/ idtypes,ioState) // PA: there is no special first menu where getIdType :: !(MenuStateHandle .pst) -> *((Id,MenuType),!MenuStateHandle .pst) getIdType msH # (id,msH) = menuStateHandleGetMenuId msH = ((id,"Menu"),msH) // Determine the index position of a menu. getMenuPos :: !Id !(IOSt .l) -> (!Maybe Index,!IOSt .l) getMenuPos id ioState # (found,mDevice,ioState) = ioStGetDevice MenuDevice ioState | not found = (Nothing,ioState) | otherwise # mHs = menuSystemStateGetMenuHandles mDevice (optIndex,msHs) = getmenuindex id 0 mHs.mMenus # ioState = ioStSetDevice (MenuSystemState {mHs & mMenus=msHs}) ioState = (optIndex,ioState) where getmenuindex :: !Id !Int ![MenuStateHandle .pst] -> (!Maybe Int,![MenuStateHandle .pst]) getmenuindex id index [mH:mHs] # (menu_id,mH) = menuStateHandleGetMenuId mH | id==menu_id = (Just index,[mH:mHs]) | otherwise # (optIndex,mHs) = getmenuindex id (index+1) mHs = (optIndex, [mH:mHs]) getmenuindex _ _ _ = (Nothing,[]) // Set & Get the title of a menu. setMenuTitle :: !Id !Title !(IOSt .l) -> IOSt .l setMenuTitle id title ioState | id==windowMenuId = ioState | otherwise = setmenutitle id title ioState getMenuTitle :: !Id !(IOSt .l) -> (!Maybe Title,!IOSt .l) getMenuTitle id ioState = accessMenuHandles id menuStateHandleGetTitle ioState