-- Author: Andy Stewart -- Maintainer: Andy Stewart -- -- Copyright (C) 2010 Andy Stewart, all rights reserved. -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . module Manatee.Toolkit.Widget.Statusbar where import Control.Applicative import Control.Concurrent.STM import Control.Monad import Data.Sequence (Seq) import Graphics.UI.Gtk hiding (Statusbar, statusbarNew) import Manatee.Toolkit.General.Functor import Manatee.Toolkit.General.List import Manatee.Toolkit.General.STM import Manatee.Toolkit.General.Seq import Manatee.Toolkit.Gtk.Box import Manatee.Toolkit.Gtk.Container import qualified Data.Foldable as F import qualified Data.Sequence as Seq import qualified Graphics.UI.Gtk.Display.Statusbar as S type StatusbarSubitem = S.Statusbar type StatusbarInfoTable = Seq (String, String) data Statusbar = Statusbar {statusbarBox :: HBox ,statusbarInfoSubitem :: StatusbarSubitem ,statusbarInfoTable :: TVar StatusbarInfoTable ,statusbarProgressBar :: ProgressBar} -- | Create new statusbar. statusbarNew :: BoxClass b => b -> IO Statusbar statusbarNew b = do -- Status box for contain status boxes. statusBox <- hBoxNew False 0 boxPackStart (toBox b) statusBox PackNatural 0 Statusbar <$> pure statusBox <*> statusbarSubitemNew statusBox <*> newTVarIO Seq.empty <*> progressBarNew -- | Clone statusbar. statusbarClone :: BoxClass b => b -> Statusbar -> IO Statusbar statusbarClone box oldStatusbar = do -- Clone status from old statusbar. newStatusbar <- statusbarNew box replaceTVarField newStatusbar oldStatusbar statusbarInfoTable -- Update status. statusbarInfoSubitemUpdate newStatusbar return newStatusbar -- | Get info table. statusbarGetInfoTable :: Statusbar -> IO StatusbarInfoTable statusbarGetInfoTable = readTVarIO . statusbarInfoTable -- | Create new sub-statusbar. statusbarSubitemNew :: BoxClass b => b -> IO StatusbarSubitem statusbarSubitemNew b = do bar <- S.statusbarNew statusbarSetHasResizeGrip bar False -- don't show resize grip boxPackStart (toBox b) bar PackGrow 0 -- use PackGrow for grow size return bar -- | Update info status. statusbarInfoSubitemSetText :: Statusbar -> String -> IO () statusbarInfoSubitemSetText = statusbarSubitemSetText . statusbarInfoSubitem -- | Set text internal. statusbarSubitemSetText :: StatusbarSubitem -> String -> IO () statusbarSubitemSetText ss str = do id <- statusbarGetContextId ss str statusbarPush ss id str return () -- | Add new info item to info subitem. statusbarInfoItemAdd :: Statusbar -> String -> String -> IO () statusbarInfoItemAdd = statusbarInfoItemUpdate -- | Update info item. statusbarInfoItemUpdate :: Statusbar -> String -> String -> IO () statusbarInfoItemUpdate statusbar item info = statusbarApplyInfoTable statusbar (replaceOrAdd (\x -> fst x == item) (item, info)) -- | Remove info item from info subitem. statusbarInfoItemRemove :: Statusbar -> String -> IO () statusbarInfoItemRemove statusbar item = statusbarApplyInfoTable statusbar (deleteMatch (\y -> fst y == item)) -- | Apply info table. statusbarApplyInfoTable :: Statusbar -> (StatusbarInfoTable -> StatusbarInfoTable) -> IO () statusbarApplyInfoTable statusbar f = do -- Apply function. modifyTVarIO (statusbarInfoTable statusbar) f -- Update info subitem. statusbarInfoSubitemUpdate statusbar -- | Update info item subitem information. statusbarInfoSubitemUpdate :: Statusbar -> IO () statusbarInfoSubitemUpdate statusbar = do infoList <- (<<<=) F.toList (readTVarIO . statusbarInfoTable) statusbar unlessNull infoList (statusbarInfoSubitemSetText statusbar (concatMap (\x -> snd x ++ " ") infoList)) -- | Update progress status. statusbarProgressUpdate :: Statusbar -> Double -> IO () statusbarProgressUpdate (Statusbar {statusbarBox = box ,statusbarProgressBar = progressBar}) progress = do -- Show progress bar first. boxTryPack box progressBar PackNatural Nothing Nothing widgetShowAll progressBar -- Set progress. set progressBar [progressBarFraction := progress / 100] progressBarSetText progressBar (show progress ++ "%") -- Hide progress bar after reach 100% (default is 100 ms). when (progress == 100.0) $ timeoutAdd (do set progressBar [progressBarFraction := 0] containerTryRemove box progressBar return False) 100 >> return ()