-- | The @module MenuItem@ exports general resources for menu -- items. module HTk.Menuitems.MenuItem ( MenuItem, createMenuItem, menuItemMethods, HasColour(..), HasPhoto(..), SelectButton(..), ToggleButton(..), HasAccelerator(..), buttonColours ) where import HTk.Kernel.Core import HTk.Kernel.ButtonWidget import HTk.Kernel.Configuration import HTk.Kernel.Resources import HTk.Components.Image import Reactor.ReferenceVariables import Util.Computation import Events.Events import HTk.Menuitems.Menu -- ----------------------------------------------------------------------- -- class MenuContainer -- ----------------------------------------------------------------------- -- | Menu items instantiate the abstract @class MenuItem@. class GUIObject w => MenuItem w -- ----------------------------------------------------------------------- -- SelectButton -- ----------------------------------------------------------------------- -- | A select button can be selected or not selected. class ButtonWidget w => SelectButton w where -- Sets the selection state of the select button. selectionState :: Toggle -> Config w -- Gets the selection state of the select button getSelectionState :: w -> IO Toggle -- Returns an event for selection actions. selectionStateSet :: w -> Event Toggle selectionState On w = execMethod (toGUIObject w) (\ nm -> tkSelect nm) >> return w selectionState Off w = execMethod (toGUIObject w) (\ nm -> tkDeselect nm) >> return w -- ----------------------------------------------------------------------- -- Accelerator -- ----------------------------------------------------------------------- -- | Menu items can have an optional text to display as a reminder -- about a keystroke binding. class GUIObject w => HasAccelerator w where -- Sets the accelerator text. accelerator :: String -> Config w -- Gets the accelerator text. getAccelerator :: w -> IO String accelerator s w = cset w "accelerator" s getAccelerator w = cget w "accelerator" -- ----------------------------------------------------------------------- -- Toggle buttons -- ----------------------------------------------------------------------- -- | The state of a @ToggleButton@ can be toggled. class SelectButton w => ToggleButton w where -- Toggles the state of a toggle button. toggleButton :: w -> IO () toggleButton w = execMethod (toGUIObject w) (\ nm -> tkToggle nm) -- ----------------------------------------------------------------------- -- Unparsing of Button Commands -- ----------------------------------------------------------------------- tkSelect :: ObjectName -> TclScript tkSelect (MenuItemName name i) = [] tkSelect name = [show name ++ " select"] {-# INLINE tkSelect #-} tkDeselect :: ObjectName -> TclScript tkDeselect (MenuItemName name i) = [] tkDeselect name = [show name ++ " deselect"] {-# INLINE tkDeselect #-} tkToggle :: ObjectName -> TclScript tkToggle (MenuItemName name i) = [] tkToggle name = [show name ++ " toggle"] {-# INLINE tkToggle #-} tkButtonCmd :: ObjectID -> TclCmd tkButtonCmd key = "Clicked " ++ show key {-# INLINE tkButtonCmd #-} -- ----------------------------------------------------------------------- -- MenuItem creation -- ----------------------------------------------------------------------- -- | Internal. createMenuItem :: MenuItem w => Menu -> MenuItemKind -> (GUIOBJECT -> w) -> [Config w] -> IO w createMenuItem menu@(Menu _ r) kind wrap ol = do i <- getRef r setRef r (i + 1) w <- createGUIObject (toGUIObject menu) (MENUITEM kind i) menuItemMethods let mi = wrap w configure mi ol -- ----------------------------------------------------------------------- -- item methods -- ----------------------------------------------------------------------- -- | Internal. menuItemMethods :: Methods menuItemMethods = Methods tkGetMenuItemConfig tkSetMenuItemConfigs tkCreateMenuItem (packCmd voidMethods) (gridCmd voidMethods) (destroyCmd voidMethods) (bindCmd voidMethods) (unbindCmd voidMethods) (cleanupCmd defMethods) -- ----------------------------------------------------------------------- -- unparsing of menu commands -- ----------------------------------------------------------------------- tkCreateMenuItem :: ObjectName -> ObjectKind -> ObjectName -> ObjectID -> [ConfigOption] -> TclScript tkCreateMenuItem nm kind _ {-nm-} _ args = tkCreateMenuItem' kind nm args' where args' = filter (not . isIllegalMenuItemConfig . first) args tkCreateMenuItem' :: ObjectKind -> ObjectName -> [ConfigOption] -> TclScript tkCreateMenuItem' kind menu opts = [show menu ++ " add " ++ (show kind) ++ " " ++ (showECO opts)] tkGetMenuItemConfig :: ObjectName -> ConfigID -> TclScript tkGetMenuItemConfig (MenuItemName name i) "text" = [(show name) ++ " entrycget " ++ (show i) ++ " -label"] tkGetMenuItemConfig (MenuItemName name i) cid | (isIllegalMenuItemConfig cid ) = [] tkGetMenuItemConfig (MenuItemName name i) cid = [show name ++ " entrycget " ++ show i ++ " -" ++ cid] tkGetMenuItemConfig _ _ = [] tkSetMenuItemConfigs :: ObjectName -> [ConfigOption] -> TclScript tkSetMenuItemConfigs (MenuItemName name i) args = [show name ++ " entryconfigure " ++ (show i) ++ " " ++ showECO args] tkSetMenuItemConfigs _ _ = [] showECO :: [ConfigOption] -> String showECO [] = "" showECO (("text",v) : ecl) = showConfig ("label", v) ++ " " ++ showECO ecl showECO (x : ecl) = showConfig x ++ " " ++ showECO ecl first (a, b) = a -- ----------------------------------------------------------------------- -- filtering of configs -- ----------------------------------------------------------------------- isIllegalMenuItemConfig :: ConfigID -> Bool isIllegalMenuItemConfig "indicatoron" = True isIllegalMenuItemConfig "disabledforeground" = True isIllegalMenuItemConfig "borderwidth" = True isIllegalMenuItemConfig "relief" = True isIllegalMenuItemConfig "cursor" = True isIllegalMenuItemConfig "takefocus" = True isIllegalMenuItemConfig "highlightbackground" = True isIllegalMenuItemConfig "highlightcolor" = True isIllegalMenuItemConfig "highlightthickness" = True isIllegalMenuItemConfig "width" = True isIllegalMenuItemConfig "height" = True isIllegalMenuItemConfig "wraplength" = True isIllegalMenuItemConfig "anchor" = True isIllegalMenuItemConfig "justify" = True isIllegalMenuItemConfig _ = False