content: -- | Like the vertical bar, but this widget automatically updates
  -- itself with a callback at fixed intervals.
  module System.Taffybar.Widget.Generic.PollingBar (
    -- * Types
    VerticalBarHandle,
    BarConfig(..),
    BarDirection(..),
    -- * Constructors and accessors
    pollingBarNew,
    verticalBarFromCallback,
    defaultBarConfig
    ) where
  
  import Control.Concurrent
  import Control.Exception.Enclosed ( tryAny )
  import qualified GI.Gtk
  import System.Taffybar.Widget.Util ( backgroundLoop )
  import Control.Monad.IO.Class
  
  import System.Taffybar.Widget.Generic.VerticalBar
  
  verticalBarFromCallback :: MonadIO m
                          => BarConfig -> IO Double -> m GI.Gtk.Widget
  verticalBarFromCallback cfg action = liftIO $ do
    (drawArea, h) <- verticalBarNew cfg
    _ <- GI.Gtk.onWidgetRealize drawArea $ backgroundLoop $ do
        esample <- tryAny action
        traverse (verticalBarSetPercent h) esample
    return drawArea
  
  pollingBarNew :: MonadIO m
                => BarConfig -> Double -> IO Double -> m GI.Gtk.Widget
  pollingBarNew cfg pollSeconds action =
    liftIO $
    verticalBarFromCallback cfg $ action <* delay
    where delay = threadDelay $ floor (pollSeconds * 1000000)
  