|
| 1 | +{-# LANGUAGE LambdaCase #-} |
| 2 | +{-# LANGUAGE OverloadedStrings #-} |
| 3 | + |
| 4 | +module TaffybarConfig.WidgetUtil |
| 5 | + ( decorateWithClassAndBox, |
| 6 | + decorateWithClassAndBoxM, |
| 7 | + setFixedLabelWidth, |
| 8 | + setLabelAlignmentRecursively, |
| 9 | + stackInPill, |
| 10 | + usageLogoWidget, |
| 11 | + ) |
| 12 | +where |
| 13 | + |
| 14 | +import Control.Monad.IO.Class (MonadIO, liftIO) |
| 15 | +import Data.Foldable (for_) |
| 16 | +import Data.GI.Base (castTo) |
| 17 | +import Data.Int (Int32) |
| 18 | +import Data.Text (Text) |
| 19 | +import qualified GI.Gtk as Gtk |
| 20 | +import qualified GI.Pango as Pango |
| 21 | +import System.Environment.XDG.BaseDir (getUserConfigFile) |
| 22 | +import System.Taffybar.Context (TaffyIO) |
| 23 | +import System.Taffybar.Widget.Util |
| 24 | + ( buildContentsBox, |
| 25 | + pixbufNewFromFileAtScaleByHeight, |
| 26 | + widgetSetClassGI, |
| 27 | + ) |
| 28 | + |
| 29 | +-- | Wrap the widget in a "TaffyBox" (via 'buildContentsBox') and add a CSS class. |
| 30 | +decorateWithClassAndBox :: (MonadIO m) => Text -> Gtk.Widget -> m Gtk.Widget |
| 31 | +decorateWithClassAndBox klass widget = do |
| 32 | + boxed <- buildContentsBox widget |
| 33 | + widgetSetClassGI boxed klass |
| 34 | + |
| 35 | +decorateWithClassAndBoxM :: (MonadIO m) => Text -> m Gtk.Widget -> m Gtk.Widget |
| 36 | +decorateWithClassAndBoxM klass builder = |
| 37 | + builder >>= decorateWithClassAndBox klass |
| 38 | + |
| 39 | +forEachLabelRecursively :: Gtk.Widget -> (Gtk.Label -> IO ()) -> IO () |
| 40 | +forEachLabelRecursively widget action = do |
| 41 | + maybeLabel <- castTo Gtk.Label widget |
| 42 | + for_ maybeLabel action |
| 43 | + |
| 44 | + maybeContainer <- castTo Gtk.Container widget |
| 45 | + case maybeContainer of |
| 46 | + Just container -> |
| 47 | + Gtk.containerGetChildren container >>= mapM_ (`forEachLabelRecursively` action) |
| 48 | + Nothing -> pure () |
| 49 | + |
| 50 | +setLabelAlignmentRecursively :: Float -> Gtk.Justification -> Gtk.Widget -> IO () |
| 51 | +setLabelAlignmentRecursively xalign justify widget = |
| 52 | + forEachLabelRecursively widget $ \label -> do |
| 53 | + Gtk.labelSetXalign label xalign |
| 54 | + Gtk.labelSetJustify label justify |
| 55 | + |
| 56 | +setFixedLabelWidth :: Int32 -> Gtk.Label -> IO () |
| 57 | +setFixedLabelWidth width label = do |
| 58 | + Gtk.labelSetWidthChars label width |
| 59 | + Gtk.labelSetMaxWidthChars label width |
| 60 | + Gtk.labelSetEllipsize label Pango.EllipsizeModeEnd |
| 61 | + |
| 62 | +stackInPill :: Text -> [TaffyIO Gtk.Widget] -> TaffyIO Gtk.Widget |
| 63 | +stackInPill klass builders = |
| 64 | + decorateWithClassAndBoxM klass $ do |
| 65 | + widgets <- sequence builders |
| 66 | + liftIO $ do |
| 67 | + box <- Gtk.boxNew Gtk.OrientationVertical 0 |
| 68 | + mapM_ (\w -> Gtk.boxPackStart box w False False 0) widgets |
| 69 | + Gtk.widgetShowAll box |
| 70 | + Gtk.toWidget box |
| 71 | + |
| 72 | +usageLogoWidget :: FilePath -> Text -> IO Gtk.Widget |
| 73 | +usageLogoWidget iconFile tooltip = do |
| 74 | + iconPath <- getUserConfigFile "taffybar" ("icons/" <> iconFile) |
| 75 | + iconWidget <- |
| 76 | + pixbufNewFromFileAtScaleByHeight 18 iconPath >>= \case |
| 77 | + Right pixbuf -> Gtk.toWidget =<< Gtk.imageNewFromPixbuf (Just pixbuf) |
| 78 | + Left _ -> Gtk.toWidget =<< Gtk.labelNew (Just "?") |
| 79 | + Gtk.widgetSetTooltipText iconWidget (Just tooltip) |
| 80 | + widgetSetClassGI iconWidget "usage-logo" |
0 commit comments