packages feed

hbro-1.2.0.0: library/Hbro/Gui/PromptBar/Signals.hs

{-# LANGUAGE TemplateHaskell #-}
module Hbro.Gui.PromptBar.Signals (
-- * Utils
    onEntryCancelled,
    onEntryChanged,
    onEntryActivated,
-- * Signals
    Cancelled(..),
    Changed(..),
    Activated(..),
    Signals,
    cancelledL,
    changedL,
    validatedL,
    initSignals,
    attach,
) where

-- {{{ Imports
-- import Hbro.Error
import Hbro.Gdk.KeyVal
import Hbro.Logger
import Hbro.Prelude hiding(on)

import Control.Lens

import Graphics.UI.Gtk.Abstract.Widget
import Graphics.UI.Gtk.Entry.Editable
import Graphics.UI.Gtk.Entry.Entry
import Graphics.UI.Gtk.Gdk.EventM as Gdk

import System.Glib.Signals
-- }}}


-- {{{ Utils
onEntryCancelled :: (BaseIO m, EntryClass t) => t -> (Cancelled -> IO ()) -> m (ConnectId t)
onEntryCancelled theEntry f = gSync . on theEntry keyPressEvent $ do
    key <- KeyVal <$> eventKeyVal
    io . when (key == _Escape) $ do
        value <- entryGetText theEntry
        debugM "hbro.prompt" $ "Prompt cancelled with value: " ++ value
        f (Cancelled value)
    return False

onEntryChanged :: (BaseIO m, EditableClass t, EntryClass t) => t -> (Changed -> IO ()) -> m (ConnectId t)
onEntryChanged theEntry f = gSync . on theEntry editableChanged $ do
    value <- entryGetText theEntry
    debugM "hbro.prompt" $ "Prompt value changed to: " ++ value
    f (Changed value)


onEntryActivated :: (BaseIO m, EntryClass t) => t -> (Activated -> IO ()) -> m (ConnectId t)
onEntryActivated theEntry f = gSync . on theEntry entryActivated $ do
    value <- entryGetText theEntry
    debugM "hbro.prompt" $ "Prompt activated with value: " ++ value
    f (Activated value)
-- }}}

-- {{{ Types
data Cancelled = Cancelled Text
instance Describable Cancelled where describe _ = "PromptCancelled"

data Changed   = Changed Text
instance Describable Changed where describe _ = "PromptChanged"

data Activated = Activated Text
instance Describable Activated where describe _ = "PromptActivated"

data Signals = Signals
    { _cancelled   :: TMVar Cancelled
    , _changed     :: TMVar Changed
    , _validated   :: TMVar Activated
    }

makeLensesWith ?? ''Signals $ lensRules
    & lensField .~ (\name -> Just (tail name ++ "L"))
-- }}}

initSignals :: (BaseIO m) => m Signals
initSignals = io (Signals <$> newEmptyTMVarIO <*> newEmptyTMVarIO <*> newEmptyTMVarIO)


attach :: (BaseIO m, EditableClass t, EntryClass t) => t -> Signals -> m ()
attach entry signals = void $ sequence
    [ onEntryCancelled entry $ void . atomically . tryPutTMVar (signals^.cancelledL)
    , onEntryChanged   entry $ void . atomically . tryPutTMVar (signals^.changedL)
    , onEntryActivated entry $ void . atomically . tryPutTMVar (signals^.validatedL)
    ]