{-# LANGUAGE TypeOperators, Arrows, TypeFamilies, Rank2Types #-} module JuicyBar.GTKDock (label, Text(..), Color(..), Click(..), Tooltip(..), run, UICircuit, fromCircuit) where import Data.Record as Record import Data.Record.Optionality import qualified Graphics.UI.Gtk as Gtk import Graphics.UI.Gtk.Windows.Window (windowSetTypeHint,WindowTypeHint(..)) import Graphics.UI.Gtk.Gdk.EventM (eventButton, tryEvent, MouseButton(..)) import qualified Graphics.UI.Grapefruit.Circuit as UICircuit import Graphics.UI.Grapefruit.Circuit hiding (run) import Graphics.UI.Grapefruit.Item import Graphics.UI.Grapefruit.GTK.Connector as GTKConnector import Graphics.UI.Grapefruit.GTK import Graphics.UI.Grapefruit.GTK.Item import FRP.Grapefruit.Setup hiding (run) import FRP.Grapefruit.Circuit import FRP.Grapefruit.Signal import FRP.Grapefruit.Signal.Discrete as DSignal import FRP.Grapefruit.Signal.Segmented as SSignal import Control.Arrow import Control.Monad.Trans (liftIO) data Label = Label { gtkLabel :: Gtk.Label , gtkEvBox :: Gtk.EventBox , gtkToolTip :: Gtk.Tooltips } createLabel :: IO Label createLabel = do l <- Gtk.labelNew Nothing e <- Gtk.eventBoxNew t <- Gtk.tooltipsNew e `Gtk.containerAdd` l Gtk.widgetModifyBg e Gtk.StateNormal (Gtk.Color 0 0 0) Gtk.widgetModifyFg l Gtk.StateNormal (Gtk.Color 65535 65535 65535) return Label { gtkLabel = l, gtkEvBox = e, gtkToolTip = t } labelToWidget :: Label -> Gtk.Widget labelToWidget l = Gtk.toWidget $ gtkEvBox l data Text = Text data Closure = Closure data Click = Click data Color = Color data Tooltip = Tooltip dockWindow :: Box UIItem Widget Window GTK X (X :& Closure ::: DSignal `Of` ()) dockWindow = windowBox createWindow Gtk.toWindow Gtk.containerAdd X (X :& Closure := eventProducer Gtk.onDestroy) where createWindow = do window <- Gtk.windowNew Gtk.windowSetDefaultSize window 1280 (-1) -- XXX windowSetTypeHint window WindowTypeHintDock Gtk.widgetModifyBg window Gtk.StateNormal (Gtk.Color 0 0 0) return window label :: Brick Widget GTK (X :& Req Text ::: SSignal `Of` String :& Opt Color ::: SSignal `Of` Gtk.Color :& Opt Tooltip ::: SSignal `Of` String) (X :& Click ::: DSignal `Of` ()) label = widgetBrick createLabel labelToWidget (X :& Text := (\l -> attrConsumer Gtk.labelLabel (gtkLabel l)) :& Color := (\l -> SSignal.consumer (Gtk.widgetModifyFg (gtkLabel l) Gtk.StateNormal)) :& Tooltip := (\l -> SSignal.consumer (\text -> Gtk.tooltipsSetTip (gtkToolTip l) (gtkEvBox l) text "")) ) (X :& Click := (\l -> eventProducer onClicked (gtkEvBox l))) onClicked :: (Gtk.WidgetClass b) => b -> IO () -> IO (Gtk.ConnectId b) onClicked widget handler = Gtk.on widget Gtk.buttonPressEvent callback where callback = tryEvent $ do LeftButton <- eventButton liftIO handler -- TODO: make spacing dependent on font size hbox :: Box UICircuit Widget Widget GTK X X hbox = widgetBox (fmap Gtk.toBox (Gtk.hBoxNew False 10)) Gtk.toWidget (\box widg -> Gtk.boxPackStart box widg Gtk.PackNatural 0) X X mainCircuit :: UICircuit Widget GTK era () () -> UICircuit Window GTK era () (DSignal era ()) mainCircuit content = proc _ -> do X :& Closure := closure `With` X `With` _ <- mainWindow -< X `With` X `With` () returnA -< closure where mainWindow = dockWindow `with` hbox `with` content run :: (forall era . UICircuit Widget GTK era () ()) -> IO () run content = UICircuit.run GTK (mainCircuit content) ()