{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} -- | -- Description: Low-Level Tcl\/Tk interface module HTk.Toplevel.HTk ( requirePackage, forgetPackage, isPackageAvailable, isTixAvailable, -- basic ressources module HTk.Kernel.Resources, module HTk.Kernel.GUIValue, module HTk.Kernel.Font, module HTk.Kernel.Geometry, module HTk.Kernel.Colour, module HTk.Kernel.Tooltip, module HTk.Kernel.TkVariables, module Events.Synchronized, module Util.Computation, module HTk.Kernel.Configuration, module HTk.Kernel.BaseClasses, module HTk.Kernel.Cursor, -- text items module HTk.Textitems.TextTag, module HTk.Textitems.Mark, module HTk.Textitems.EmbeddedTextWin, -- window submodules module HTk.Containers.Window, module HTk.Containers.Toplevel, -- widget submodules module HTk.Containers.Frame, module HTk.Widgets.Label, module HTk.Widgets.Message, module HTk.Widgets.Entry, module HTk.Widgets.Button, module HTk.Widgets.CheckButton, module HTk.Widgets.RadioButton, module HTk.Widgets.MenuButton, module HTk.Widgets.Canvas, module HTk.Widgets.Editor, module HTk.Widgets.ListBox, module HTk.Widgets.OptionMenu, module HTk.Widgets.Scale, module HTk.Widgets.ScrollBar, module HTk.Devices.Screen, module HTk.Containers.Box, -- tix submodules module HTk.Tix.NoteBook, module HTk.Tix.LabelFrame, module HTk.Tix.PanedWindow, module HTk.Widgets.ComboBox, -- devices submodules module HTk.Devices.Bell, module HTk.Devices.Printer, -- menu / menuitem submodules module HTk.Menuitems.Menu, module HTk.Menuitems.MenuCascade, module HTk.Menuitems.MenuCommand, module HTk.Menuitems.MenuCheckButton, module HTk.Menuitems.MenuRadioButton, module HTk.Menuitems.MenuSeparator, -- canvasitem submodules module HTk.Canvasitems.CanvasItem, module HTk.Canvasitems.Arc, module HTk.Canvasitems.Line, module HTk.Canvasitems.Oval, module HTk.Canvasitems.Polygon, module HTk.Canvasitems.Rectangle, module HTk.Canvasitems.ImageItem, module HTk.Canvasitems.BitMapItem, module HTk.Canvasitems.TextItem, module HTk.Canvasitems.CanvasTag, module HTk.Canvasitems.EmbeddedCanvasWin, -- components submodules module HTk.Components.Index, module HTk.Components.BitMap, module HTk.Components.Image, module HTk.Components.Focus, module HTk.Components.Icon, module HTk.Components.Selection, -- widget packing module HTk.Kernel.ButtonWidget, module HTk.Kernel.Packer, module HTk.Kernel.PackOptions, module HTk.Kernel.GridPackOptions, -- events module Events.Events, module HTk.Kernel.EventInfo, module Events.Spawn, module Events.Channels, WishEvent(..), WishEventType(..), WishEventModifier(..), KeySym(..), bind, bindSimple, bindPath, bindPathSimple, HasCommand(..), delayWish, -- other basic stuff // TD: sort out! initHTk, -- :: [Config HTk] -> IO HTk -- initHTk initialises HTk. withdrawMainWin, -- :: Config HTk -- withDraw as a configuration resourceFile, -- :: String-> Config HTk -- loads resource file finishHTk, -- :: IO () -- waits for all wish to finish and then terminates withdrawWish, -- :: IO () -- withdrawWish withdraws the wish window. HTk, updateAllTasks, updateIdleTasks, Destructible(..), Destroyable(..), cleanupWish, getHTk, ) where import Control.Concurrent import Events.Channels import Events.Destructible import Events.Events import Events.Spawn import Events.Synchronized import HTk.Canvasitems.Arc import HTk.Canvasitems.BitMapItem import HTk.Canvasitems.CanvasItem hiding (Canvas) import HTk.Canvasitems.CanvasTag import HTk.Canvasitems.EmbeddedCanvasWin import HTk.Canvasitems.ImageItem import HTk.Canvasitems.Line import HTk.Canvasitems.Oval import HTk.Canvasitems.Polygon import HTk.Canvasitems.Rectangle import HTk.Canvasitems.TextItem import HTk.Components.BitMap import HTk.Components.Focus import HTk.Components.Icon import HTk.Components.Image import HTk.Components.Index import HTk.Components.Selection import HTk.Containers.Box import HTk.Containers.Frame import HTk.Containers.Toplevel import HTk.Containers.Window import HTk.Devices.Bell import HTk.Devices.Printer import HTk.Devices.Screen import HTk.Kernel.BaseClasses import HTk.Kernel.ButtonWidget import HTk.Kernel.Colour import HTk.Kernel.Configuration import HTk.Kernel.Core import HTk.Kernel.Cursor import HTk.Kernel.EventInfo import HTk.Kernel.Font import HTk.Kernel.GUIValue import HTk.Kernel.Geometry import HTk.Kernel.GridPackOptions import HTk.Kernel.PackOptions import HTk.Kernel.Packer import HTk.Kernel.Resources import HTk.Kernel.TkVariables import HTk.Kernel.Tooltip import HTk.Kernel.Wish import HTk.Menuitems.Menu import HTk.Menuitems.MenuCascade import HTk.Menuitems.MenuCheckButton import HTk.Menuitems.MenuCommand import HTk.Menuitems.MenuRadioButton import HTk.Menuitems.MenuSeparator import HTk.Textitems.EmbeddedTextWin import HTk.Textitems.Mark import HTk.Textitems.TextTag import HTk.Tix.LabelFrame import HTk.Tix.NoteBook import HTk.Tix.PanedWindow import HTk.Widgets.Button import HTk.Widgets.Canvas import HTk.Widgets.CheckButton import HTk.Widgets.ComboBox import HTk.Widgets.Editor import HTk.Widgets.Entry import HTk.Widgets.Label import HTk.Widgets.ListBox import HTk.Widgets.MenuButton import HTk.Widgets.Message import HTk.Widgets.OptionMenu import HTk.Widgets.RadioButton import HTk.Widgets.Scale import HTk.Widgets.ScrollBar import System.IO.Unsafe import Util.Computation -- ----------------------------------------------------------------------- -- type HTk and its instances -- ----------------------------------------------------------------------- -- | The @HTk@ datatype - a handle for the wish instance and -- the main window. newtype HTk = HTk GUIOBJECT -- | Internal. instance GUIObject HTk where toGUIObject (HTk obj) = obj cname _ = "HTk" -- | Internal. instance Eq HTk where (HTk obj1) == (HTk obj2) = obj1 == obj2 -- | The wish instance can be destroyed. instance Destroyable HTk where -- Destroys the wish instance. destroy = destroy . toGUIObject -- | The wish instance is associated with the main window (with various -- configurations and actions concerning its stacking order, display -- status, screen, aspect ratio etc.). instance Window HTk -- | The main window is a container for widgets. You can pack widgets to -- the main window via pack or grid command in the -- @module HTk.Kernel.Packer@. instance Container HTk -- | You can synchronize on the wish instance. instance Synchronized HTk where -- Synchronizes on the wish instance. synchronize = synchronize . toGUIObject -- ----------------------------------------------------------------------- -- commands -- ----------------------------------------------------------------------- --- @doc initHTk -- Only one HTk is allowed to exist, of course. It is initialised -- by whichever of getHTk and initHTk is called first; once initialised -- initHTk may not be called again. So in general, where initHTk is -- used, you should use it before any other HTk action. theHTkMVar :: MVar (Maybe HTk) theHTkMVar = unsafePerformIO (newMVar Nothing) {-# NOINLINE theHTkMVar #-} -- | Initializes HTk. initHTk :: [Config HTk] -- ^ the list of configuration options for the wish -- instance \/ main window. -> IO HTk -- ^ The wish instance. initHTk cnf = do htkOpt <- takeMVar theHTkMVar htk <- case htkOpt of Nothing -> newHTk cnf Just htk -> return htk -- should we configure again? putMVar theHTkMVar (Just htk) return htk --- @doc getHTk -- getHTk retrieves the current HTk (initialising if necessary). getHTk :: IO HTk getHTk = do htkOpt <- takeMVar theHTkMVar htk <- case htkOpt of Nothing -> newHTk [] Just htk -> return htk putMVar theHTkMVar (Just htk) return htk --- @doc newHTk -- newHTk actually creates a new HTk. DO NOT call this except -- by initHTk or getHTk! newHTk :: [Config HTk] -> IO HTk newHTk opts = do obj <- createHTkObject htkMethods configure (HTk obj) opts return (HTk obj) --- @doc withdrawWish -- withdrawWish withdraws the wish window. withdrawWish :: IO () withdrawWish = do htk <- getHTk withdraw htk -- | Withdraws the main window. withdrawMainWin :: Config HTk withdrawMainWin htk = do withdraw htk return htk --- @doc readResourceFile -- Load a resource file -- A resource files specifies the default options for fonts, colours, &c. resourceFile :: String-> Config HTk resourceFile file htk = do execCmd ("option readfile "++ file++ " startup") -- "startup" is the priority; we could make this user- -- configurable if wished? return htk --- @doc finishHTk -- waits for HTk to finish, and calls cleanupWish to clean up. -- This rebinds the Destroy event of the main window, so -- do not call this function if you have bound anything to that. -- In that case, call cleanupWish after you have finished with wish. finishHTk :: IO () finishHTk = do htk <- getHTk (htk_destr, _) <- bindSimple htk Destroy sync htk_destr cleanupWish -- ----------------------------------------------------------------------- -- HTk methods -- ----------------------------------------------------------------------- htkMethods = Methods tkGetToplevelConfig tkSetToplevelConfigs (createCmd voidMethods) (packCmd voidMethods) (gridCmd voidMethods) (destroyCmd defMethods) (bindCmd defMethods) (unbindCmd defMethods) (cleanupCmd defMethods) -- ----------------------------------------------------------------------- -- application updates -- ----------------------------------------------------------------------- -- | Updates all tasks. updateAllTasks :: IO () updateAllTasks = execTclScript ["update"] -- | Updates idle tasks. updateIdleTasks :: IO () updateIdleTasks = execTclScript ["update idletasks"] -- ----------------------------------------------------------------------- -- application Name -- ----------------------------------------------------------------------- -- | The wish instance has a value - the application name. instance GUIValue v => HasValue HTk v where -- Sets the application name. value aname htk = do execTclScript ["tk appname " ++ show aname] return htk -- Gets the application name. getValue _ = evalTclScript ["tk appname"] >>= creadTk