{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} -- | This module provides access to text tags inside an editor widget. module HTk.Textitems.TextTag ( TextTag, createTextTag, addTextTag, lowerTextTag, raiseTextTag, removeTextTag, lmargin1, getLmargin1, lmargin2, getLmargin2, rmargin, getRmargin, offset, getOffset, overstrike, getOverstrike, underlined, getUnderlined, bgstipple, getBgstipple, fgstipple, getFgstipple ) where import HTk.Kernel.Core import HTk.Kernel.Resources import HTk.Kernel.Geometry import HTk.Kernel.Configuration import HTk.Widgets.Editor import HTk.Components.BitMap import HTk.Components.Index import Util.Computation import Events.Synchronized import Events.Destructible -- ----------------------------------------------------------------------- -- TextTag type -- ----------------------------------------------------------------------- -- | The @TextTag@ datatype. data TextTag = TextTag Editor GUIOBJECT -- ----------------------------------------------------------------------- -- construction -- ----------------------------------------------------------------------- -- | Creates a text tag inside an editor widget and returns a handler. createTextTag :: (HasIndex Editor i1 BaseIndex, HasIndex Editor i2 BaseIndex) => Editor -- ^ the concerned editor widget. -> i1 -- ^ the start index. -> i2 -- ^ the end index. -> [Config TextTag] -- ^ the list of configuration options for this text tag. -> IO TextTag -- ^ A text tag. createTextTag ed i1 i2 cnf = do bi1 <- getBaseIndex ed i1 bi2 <- getBaseIndex ed i2 w <- createGUIObject (toGUIObject ed) (TEXTTAG (map unparse [bi1::BaseIndex,bi2])) tagMethods configure (TextTag ed w) cnf where unparse (IndexNo _) = GUIVALUE HaskellTk "" unparse (IndexText s) = GUIVALUE HaskellTk ("{" ++ s ++ "}") unparse p = GUIVALUE HaskellTk (show p ++ " ") -- ----------------------------------------------------------------------- -- instances -- ----------------------------------------------------------------------- -- | Internal. instance Eq TextTag where (TextTag _ w1) == (TextTag _ w2) = (toGUIObject w1) == (toGUIObject w2) -- | Internal. instance GUIObject TextTag where toGUIObject (TextTag _ w) = w cname _ = "TextTag" -- | A text tag can be destroyed. instance Destroyable TextTag where -- Destroys a text tag. destroy = destroy . toGUIObject -- | A text tag has a configureable border. instance HasBorder TextTag -- | A text tag has a configureable foregroud and background colour. instance HasColour TextTag where legalColourID = hasForeGroundColour -- | A text tag has a configureable font. instance HasFont TextTag -- | A text tag has a configureable text justification. instance HasJustify TextTag -- | A text tag has a configureable line spacing. instance HasLineSpacing TextTag -- | A text tag has adjustable tab stops. instance HasTabulators TextTag -- | You can synchronize on a text tag object. instance Synchronized TextTag where -- Synchronizes on a text tag object. synchronize = synchronize . toGUIObject -- ----------------------------------------------------------------------- -- Tag Commands -- ----------------------------------------------------------------------- -- | Adds the specified text range to a text tag. addTextTag :: (HasIndex Editor i1 BaseIndex, HasIndex Editor i2 BaseIndex) => TextTag -- ^ the concerned text tag. -> i1 -- ^ the start index. -> i2 -- ^ the end index. -> IO () -- ^ None. addTextTag tag@(TextTag tp _) start end = synchronize tag ( do start' <- getBaseIndex tp start end' <- getBaseIndex tp end execMethod tag (\nm -> tkTagAdd nm start' end') ) -- | Removes the specified text range from a text tag. removeTextTag :: (HasIndex Editor i1 BaseIndex, HasIndex Editor i2 BaseIndex) => TextTag -- ^ the concerned text tag. -> i1 -- ^ the start index. -> i2 -- ^ the end index. -> IO () -- ^ None. removeTextTag tag @ (TextTag tp _) start end = synchronize tag ( do start' <- getBaseIndex tp start end' <- getBaseIndex tp end execMethod tag (\nm -> tkTagRemove nm start' end') ) -- | Lowers the text tag. lowerTextTag :: TextTag -- ^ the concerned text tag. -> IO () -- ^ None. lowerTextTag tag = execMethod tag (\nm -> tkTagLower nm) -- | Raises the given text tag. raiseTextTag :: TextTag -- ^ the concerned text tag. -> IO () -- ^ None. raiseTextTag tag = execMethod tag (\nm -> tkTagRaise nm) -- ----------------------------------------------------------------------- -- tag configure options -- ----------------------------------------------------------------------- -- | Sets the normal left intend for a line. lmargin1 :: Distance -> Config TextTag lmargin1 s tag = cset tag "lmargin1" s -- | Gets the normal left intend for a line. getLmargin1 :: TextTag -> IO Distance getLmargin1 tag = cget tag "lmargin1" -- | Sets the intend for a part of a line that gets wrapped. lmargin2 :: Distance -> Config TextTag lmargin2 s tag = cset tag "lmargin2" s -- | Gets the intend for a part of a line that gets wrapped. getLmargin2 :: TextTag -> IO Distance getLmargin2 tag = cget tag "lmargin2" -- | Sets the right-hand margin. rmargin :: Distance -> Config TextTag rmargin s tag = cset tag "rmargin" s -- | Gets the right-hand margin. getRmargin :: TextTag -> IO Distance getRmargin tag = cget tag "rmargin" -- | Sets the baseline offset (positive for superscripts). offset :: Distance -> Config TextTag offset s tag = cset tag "offset" s -- | Gets the baseline offset. getOffset :: TextTag -> IO Distance getOffset tag = cget tag "offset" -- | If @True@, the text is drawn with a horizontal line through -- it. overstrike :: Toggle -> Config TextTag overstrike s tag = cset tag "overstrike" s -- | Gets the current overstrike setting. getOverstrike :: TextTag -> IO Toggle getOverstrike tag = cget tag "overstrike" -- | If @True@, the text is underlined. underlined :: Toggle -> Config TextTag underlined s tag = cset tag "underline" s -- | Gets the current underline setting. getUnderlined :: TextTag -> IO Toggle getUnderlined tag = cget tag "underline" -- | Sets a stipple pattern for the background colour. bgstipple :: BitMapHandle -> Config TextTag bgstipple s tag = setBitMapHandle tag "bgstipple" s False -- | Gets the stipple pattern for the background colour. getBgstipple ::TextTag -> IO BitMapHandle getBgstipple tag = getBitMapHandle tag "bgstipple" -- | Sets a stipple pattern for the foreground colour. fgstipple :: BitMapHandle -> Config TextTag fgstipple s tag = setBitMapHandle tag "fgstipple" s False -- | Gets the stipple pattern for the foreground colour. getFgstipple :: TextTag -> IO BitMapHandle getFgstipple tag = getBitMapHandle tag "fgstipple" -- ----------------------------------------------------------------------- -- Index: Tag First and Last -- ----------------------------------------------------------------------- -- | Internal. instance HasIndex Editor (TextTag, First) BaseIndex where getBaseIndex tp (tag,_) = synchronize tag ( do (pnm, tnm) <- getTagName tag return (IndexText (show tnm ++ ".first")) ) -- | Internal. instance HasIndex Editor (TextTag, Last) BaseIndex where getBaseIndex tp (tag,_) = synchronize tag ( do (pnm, tnm) <- getTagName tag return (IndexText (show tnm ++ ".last")) ) getTagName :: GUIObject w => w -> IO (ObjectName, TextItemName) getTagName tag = do TextPaneItemName pnm tid <- getObjectName (toGUIObject tag) return (pnm, tid) -- ----------------------------------------------------------------------- -- tag methods -- ----------------------------------------------------------------------- tagMethods = Methods tkGetTextTagConfig tkSetTextTagConfigs tkCreateTextTag (packCmd voidMethods) (gridCmd voidMethods) tkTagDelete tkBindTextTag tkUnbindTextTag (cleanupCmd defMethods) -- ----------------------------------------------------------------------- -- unparsing of tag commands -- ----------------------------------------------------------------------- tkGetTextTagConfig :: ObjectName -> ConfigID -> TclScript tkGetTextTagConfig (TextPaneItemName name tnm) cid = [(show name) ++ " tag cget " ++ (show tnm) ++ " -" ++ cid] tkGetTextTagConfig _ _ = [] {-# INLINE tkGetTextTagConfig #-} tkSetTextTagConfigs :: ObjectName -> [ConfigOption] -> TclScript tkSetTextTagConfigs _ [] = [] tkSetTextTagConfigs (TextPaneItemName name (tnm @ (TextTagID k))) args = [show name ++ " tag configure " ++ show tnm ++ " " ++ showConfigs args] tkSetTextTagConfigs _ _ = [] {-# INLINE tkSetTextTagConfigs #-} tkCreateTextTag :: ObjectName -> ObjectKind -> ObjectName -> ObjectID -> [ConfigOption] -> TclScript tkCreateTextTag _ (TEXTTAG il) (TextPaneItemName name tnm) _ args = [show name ++ " tag add " ++ show tnm ++ " " ++ concat (map unfold il) ++ " " ++ (showConfigs args)] where unfold (GUIVALUE _ str) = str ++ " " --tkCreateTextTag _ _ _ _ _ = [] {-# INLINE tkCreateTextTag #-} tkTagAdd :: ObjectName -> BaseIndex -> BaseIndex -> TclScript tkTagAdd (TextPaneItemName name tnm) start end = [show name ++ " tag add " ++ show tnm ++ " " ++ show start ++ " " ++ show end] tkTagAdd _ _ _ = [] {-# INLINE tkTagAdd #-} tkTagDelete :: ObjectName -> TclScript tkTagDelete (TextPaneItemName name tnm) = [show name ++ " tag delete " ++ show tnm] tkTagDelete _ = [] {-# INLINE tkTagDelete #-} tkBindTextTag :: ObjectName -> BindTag -> [WishEvent] -> EventInfoSet -> Bool -> TclScript tkBindTextTag (TextPaneItemName name tnm) bindTag wishEvents eventInfoSet _ = let doBind = show name ++ " tag bind " ++ show tnm ++ " " ++ delimitString (foldr (\ event soFar -> showP event soFar) "" wishEvents) ++ " " ++ mkBoundCmdArg bindTag eventInfoSet False in [doBind] {-# INLINE tkBindTextTag #-} tkUnbindTextTag :: ObjectName -> BindTag -> [WishEvent] -> Bool -> TclScript tkUnbindTextTag (TextPaneItemName name tnm) bindTag wishEvents _ = [show name ++ " tag bind " ++ show tnm ++ " " ++ delimitString (foldr (\ event soFar -> showP event soFar) "" wishEvents) ++ " {}"] {-# INLINE tkUnbindTextTag #-} tkTagLower :: ObjectName -> TclScript tkTagLower (TextPaneItemName name tnm) = [show name ++ " tag lower " ++ show tnm] tkTagLower _ = [] {-# INLINE tkTagLower #-} tkTagRaise :: ObjectName -> TclScript tkTagRaise (TextPaneItemName name tnm) = [show name ++ " tag raise " ++ show tnm] tkTagRaise _ = [] {-# INLINE tkTagRaise #-} tkTagRemove :: ObjectName -> BaseIndex -> BaseIndex -> TclScript tkTagRemove (TextPaneItemName name tnm) start end = [show name ++ " tag remove " ++ show tnm ++ " " ++ show start ++ " " ++ show end] tkTagRemove _ _ _ = [] {-# INLINE tkTagRemove #-}