summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/Main.hs8
-rw-r--r--app/Sensor.hs32
-rw-r--r--app/Ui.hs82
3 files changed, 81 insertions, 41 deletions
diff --git a/app/Main.hs b/app/Main.hs
index 573e6a1..f12d0d0 100644
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -187,16 +187,16 @@ createWindow args = do
Ui $
intercalate [pure (lit " ")] $
[ [lit <$> wmWorkspaces],
- [lit <$> wmName, pure fill],
+ [litShrink <$> wmName, pure fill],
[pure (lit (if args.icons then "\xf4bc " else "cpu ")), lit <$> cpu],
[pure (lit (if args.icons then "\xf035b " else "mem ")), lit <$> mem],
[pure (lit (if args.icons then "\xf0a0 " else "disk ")), lit <$> disk],
[pure (lit (if args.icons then "\xf1638 " else "io ")), lit <$> io],
[pure (lit (if args.icons then "\xf0200 " else "net ")), lit <$> net],
- [pure (lit " "), lit <$> Sensor.snd],
- [pure (lit " "), lit <$> thermal],
+ [pure (lit " "), lit <$> Sensor.snd, pure (lit " ")],
+ [pure (lit (if args.icons then "\xf2cb " else "temp ")), lit <$> thermal],
[pure (lit " "), lit <$> bat],
- [lit <$> weatherForecast],
+ -- [lit <$> weatherForecast],
[pure (lit " "), lit <$> date, pure (lit ", "), lit <$> time]
]
xcolors <- do
diff --git a/app/Sensor.hs b/app/Sensor.hs
index 2c2e860..de14783 100644
--- a/app/Sensor.hs
+++ b/app/Sensor.hs
@@ -114,16 +114,23 @@ diagram n sf = S.feedbackS [] $ proc ((), xs) -> do
x <- sf -< ()
returnA -< (P.diagram n (reverse (x : xs)), take (2 * (n - 1) + 1) (x : xs))
-thermal :: S.Sensor () String
-thermal = S.sensor (\() -> "thermal") $ \() yield -> forever do
- yield . fmt =<< parse <* sleep
+thermal :: S.Sensor () (P.Diagram [Float])
+thermal =
+ ((\x -> clamp 0 1 (x / 100)) <$$$>) $
+ diagram 1 $
+ S.sensor (\() -> "thermal") $ \() yield -> forever do
+ yield =<< parse <* sleep
where
parse = liftIO do
is <- listDirectory "/sys/class/thermal"
maximum <$> mapM (parse1 . ("/sys/class/thermal" </>)) is
parse1 fp = do
- (choice 0 [readFile (fp </> "temp") (pure . read @Int . strip)])
- fmt temp = (printf "%.1f" (fromIntegral temp / (1000 :: Float)))
+ (choice 0 [readFile (fp </> "temp") (pure . (/ 1000) . fromIntegral . read @Int . strip)])
+
+clamp :: (Ord a) => a -> a -> a -> a
+clamp hi lo
+ | hi > lo = min hi . max lo
+ | otherwise = clamp lo hi
ioStat :: S.Sensor () Int
ioStat = S.sensor (\() -> "ioStat") $ \() yield -> forever do
@@ -636,8 +643,8 @@ time =
<$> currentTimeZone
<*> currentTime
-wmName :: S.Sensor () String
-wmName = activeWindow >>> S.withDefaultS "" wmNameOf
+wmName :: S.Sensor () P.Doc
+wmName = activeWindow >>> S.withDefaultS (P.pretty "") wmNameOf
data ActiveWindow = ActiveWindow deriving (Show)
@@ -682,7 +689,7 @@ activeWindow = do
waitForEvent
)
-wmNameOf :: S.Sensor X.Window String
+wmNameOf :: S.Sensor X.Window P.Doc
wmNameOf =
S.sensor
(\win -> printf "wmNameOf %s" (show win))
@@ -716,7 +723,7 @@ wmNameOf =
waitForEvent
readWmName = do
- yield
+ yield . P.color P.Magenta . P.pretty
=<< fmap (strip . head) . liftIO . X.wcTextPropertyToTextList dpy
=<< liftIO (X.getTextProperty dpy win netWmName)
forever do
@@ -815,12 +822,15 @@ instance P.Pretty [Workspace] where
P.Col . intersperse (P.pretty " ") . map P.pretty
instance P.Pretty Workspace where
- pretty (Active s) = P.color P.White (P.pretty s)
- pretty (Inactive s) = P.color P.Cyan (P.pretty s)
+ pretty (Active s) = P.color P.Cyan (P.pretty s)
+ pretty (Inactive s) = P.color P.White (P.pretty s)
(<$$>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
f <$$> x = fmap f <$> x
+(<$$$>) :: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b))
+f <$$$> x = fmap f <$$> x
+
infixl 4 <$$>
fi :: (Integral a, Num b) => a -> b
diff --git a/app/Ui.hs b/app/Ui.hs
index 2261f0a..92ef01a 100644
--- a/app/Ui.hs
+++ b/app/Ui.hs
@@ -1,6 +1,7 @@
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
@@ -12,8 +13,10 @@
module Ui
( Ui (Ui),
Block,
+ Flex (..),
lit,
fill,
+ litShrink,
pollUi,
Env (..),
Ui',
@@ -48,41 +51,39 @@ data Ui a = Ui [a]
)
data Block a
- = Lit a
- | Fill
+ = Lit Flex a
deriving (Eq, Functor, Show, Generic, NFData)
+data Flex = Flex
+ { canGrow :: Bool,
+ canShrink :: Bool
+ }
+ deriving (Eq, Show, Generic, NFData)
+
lit :: (P.Pretty a) => a -> Block P.Doc
-lit = Lit . P.pretty
+lit = Lit (Flex False False) . P.pretty
+
+litShrink :: (P.Pretty a) => a -> Block P.Doc
+litShrink = Lit (Flex False True) . P.pretty
-fill :: Block a
-fill = Fill
+fill :: Block P.Doc
+fill = Lit (Flex True False) (P.pretty "")
pollUi :: Ui (S.Sensor () (Block P.Doc)) -> S.Sensor () (Ui (Block P.Doc))
pollUi (Ui sfs) = Ui <$> S.concatS sfs
layOutUi :: Env -> Ui (Block P.Doc) -> IO Ui'
-layOutUi env (Ui bs) = layOut env (Ui' (concatMap go bs))
+layOutUi env (Ui bs) = shrinkText env =<< layOut env (Ui' (concatMap go bs))
where
- go (Lit doc) = go' doc
- go Fill =
+ go (Lit flex (P.Lit color string)) =
[ C
{ rect = def,
- fill = True,
- color = Nothing,
- string = ""
- }
- ]
-
- go' (P.Lit color string) =
- [ C
- { rect = def,
- fill = False,
..
}
]
- go' (P.Col docs) =
- concatMap go' docs
+ go (Lit flex (P.Col docs)) =
+ -- TODO bug `P.Col` needs container support in `C`
+ concatMap (go . Lit flex) docs
layOut :: Env -> Ui' -> IO Ui'
layOut env@Env {..} (Ui' cs) = do
@@ -95,12 +96,41 @@ layOut env@Env {..} (Ui' cs) = do
left <- get <* modify (+ rect.width)
pure c {rect = rect {left = left}}
- expa rwidth (c@C {fill = True} : cs) =
- do
- c {rect = c.rect {width = c.rect.width + rwidth}}
- : map (\c -> c {rect = c.rect {left = c.rect.left + rwidth}}) cs
- expa rwidth (c : cs) = c : expa rwidth cs
expa _ [] = []
+ expa 0 cs = cs
+ expa rwidth (c@C {flex = Flex False False} : cs) = c : expa rwidth cs
+ expa rwidth (c@C {flex = Flex {..}} : cs) =
+ if
+ | rwidth > 0 && canGrow ->
+ c {rect = c.rect {width = c.rect.width + rwidth}}
+ : map (\c -> c {rect = c.rect {left = c.rect.left + rwidth}}) cs
+ | rwidth < 0 && canShrink ->
+ c {rect = c.rect {width = c.rect.width + rwidth}}
+ : map (\c -> c {rect = c.rect {left = c.rect.left + rwidth}}) cs
+ | otherwise -> c : expa rwidth cs
+
+shrinkText :: Env -> Ui' -> IO Ui'
+shrinkText Env {..} (Ui' cs) = Ui' <$> mapM go cs
+ where
+ go C {..} = do
+ string' <- fit rect.width string
+ pure C {string = string', ..}
+
+ fit _ "" = pure ""
+ fit rwidth string = do
+ glyphInfo <- X.xftTextExtents dpy fnt string
+ let width = X.xglyphinfo_xOff glyphInfo
+ if width <= rwidth
+ then pure string
+ else fit' rwidth (init string)
+
+ fit' _ "" = pure ""
+ fit' rwidth string = do
+ glyphInfo <- X.xftTextExtents dpy fnt (string ++ "…")
+ let width = X.xglyphinfo_xOff glyphInfo
+ if width <= rwidth
+ then pure (string ++ "…")
+ else fit' rwidth (init string)
extents :: Env -> C -> IO Rect
extents Env {..} (C {..}) = do
@@ -158,7 +188,7 @@ data Ui' = Ui' [C] deriving (Show, Generic, NFData)
data C = C
{ rect :: Rect,
- fill :: Bool,
+ flex :: Flex,
color :: Maybe (P.Intensity, P.Color),
string :: String
}