module System.Taffybar.Widget.XDGMenu.MenuWidget
(
menuWidgetNew
)
where
import Control.Monad
import Control.Monad.IO.Class
import qualified Data.Text as T
import GI.Gtk hiding (Menu, imageMenuItemNew)
import System.Log.Logger
import System.Process
import System.Taffybar.Widget.Generic.AutoSizeImage
import System.Taffybar.Widget.Util
import System.Taffybar.Widget.XDGMenu.Menu
logHere :: Priority -> String -> IO ()
logHere :: Priority -> String -> IO ()
logHere = String -> Priority -> String -> IO ()
logM String
"System.Taffybar.Widget.XDGMenu.MenuWidget"
addItem :: (IsMenuShell msc) =>
msc
-> MenuEntry
-> IO ()
addItem :: forall msc. IsMenuShell msc => msc -> MenuEntry -> IO ()
addItem msc
ms MenuEntry
de = do
MenuItem
item <- Text -> (Int32 -> IO (Maybe Pixbuf)) -> IO MenuItem
forall (m :: * -> *).
MonadIO m =>
Text -> (Int32 -> IO (Maybe Pixbuf)) -> m MenuItem
imageMenuItemNew (MenuEntry -> Text
feName MenuEntry
de) (Maybe Text -> Int32 -> IO (Maybe Pixbuf)
getImageForMaybeIconName (MenuEntry -> Maybe Text
feIcon MenuEntry
de))
MenuItem -> Text -> IO ()
forall (m :: * -> *) o.
(MonadIO m, IsWidget o) =>
o -> Text -> m ()
setWidgetTooltipText MenuItem
item (MenuEntry -> Text
feComment MenuEntry
de)
msc -> MenuItem -> IO ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsMenuShell a, IsMenuItem b) =>
a -> b -> m ()
menuShellAppend msc
ms MenuItem
item
SignalHandlerId
_ <- MenuItem -> ((?self::MenuItem) => IO ()) -> IO SignalHandlerId
forall a (m :: * -> *).
(IsMenuItem a, MonadIO m) =>
a -> ((?self::a) => IO ()) -> m SignalHandlerId
onMenuItemActivate MenuItem
item (((?self::MenuItem) => IO ()) -> IO SignalHandlerId)
-> ((?self::MenuItem) => IO ()) -> IO SignalHandlerId
forall a b. (a -> b) -> a -> b
$ do
let cmd :: String
cmd = MenuEntry -> String
feCommand MenuEntry
de
Priority -> String -> IO ()
logHere Priority
DEBUG (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Launching '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
cmd String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"
ProcessHandle
_ <- String -> IO ProcessHandle
spawnCommand String
cmd
() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
addMenu
:: (IsMenuShell msc)
=> msc
-> Menu
-> IO ()
msc
ms Menu
fm = do
let subMenus :: [Menu]
subMenus = Menu -> [Menu]
fmSubmenus Menu
fm
items :: [MenuEntry]
items = Menu -> [MenuEntry]
fmEntries Menu
fm
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not ([MenuEntry] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [MenuEntry]
items) Bool -> Bool -> Bool
|| Bool -> Bool
not ([Menu] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Menu]
subMenus)) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
MenuItem
item <- Text -> (Int32 -> IO (Maybe Pixbuf)) -> IO MenuItem
forall (m :: * -> *).
MonadIO m =>
Text -> (Int32 -> IO (Maybe Pixbuf)) -> m MenuItem
imageMenuItemNew (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Menu -> String
fmName Menu
fm)
(Maybe Text -> Int32 -> IO (Maybe Pixbuf)
getImageForMaybeIconName (String -> Text
T.pack (String -> Text) -> Maybe String -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Menu -> Maybe String
fmIcon Menu
fm))
msc -> MenuItem -> IO ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsMenuShell a, IsMenuItem b) =>
a -> b -> m ()
menuShellAppend msc
ms MenuItem
item
Menu
subMenu <- IO Menu
forall (m :: * -> *). (HasCallStack, MonadIO m) => m Menu
menuNew
MenuItem -> Maybe Menu -> IO ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsMenuItem a, IsMenu b) =>
a -> Maybe b -> m ()
menuItemSetSubmenu MenuItem
item (Menu -> Maybe Menu
forall a. a -> Maybe a
Just Menu
subMenu)
(Menu -> IO ()) -> [Menu] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Menu -> Menu -> IO ()
forall msc. IsMenuShell msc => msc -> Menu -> IO ()
addMenu Menu
subMenu) [Menu]
subMenus
(MenuEntry -> IO ()) -> [MenuEntry] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Menu -> MenuEntry -> IO ()
forall msc. IsMenuShell msc => msc -> MenuEntry -> IO ()
addItem Menu
subMenu) [MenuEntry]
items
menuWidgetNew
:: MonadIO m
=> Maybe String
-> m GI.Gtk.Widget
Maybe String
mMenuPrefix = IO Widget -> m Widget
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Widget -> m Widget) -> IO Widget -> m Widget
forall a b. (a -> b) -> a -> b
$ do
MenuBar
mb <- IO MenuBar
forall (m :: * -> *). (HasCallStack, MonadIO m) => m MenuBar
menuBarNew
Menu
m <- Maybe String -> IO Menu
buildMenu Maybe String
mMenuPrefix
MenuBar -> Menu -> IO ()
forall msc. IsMenuShell msc => msc -> Menu -> IO ()
addMenu MenuBar
mb Menu
m
MenuBar -> IO ()
forall (m :: * -> *) a.
(HasCallStack, MonadIO m, IsWidget a) =>
a -> m ()
widgetShowAll MenuBar
mb
MenuBar -> IO Widget
forall (m :: * -> *) o. (MonadIO m, IsWidget o) => o -> m Widget
toWidget MenuBar
mb