nano-ui
Safe HaskellNone
LanguageGHC2024

NanoUI.Monad

Description

The Ui effect and the NanoUI view type: running a view, widget id scopes and keys, theme scopes, and damage requests from inside a view.

Synopsis

Documentation

type NanoUI = Eff '[Ui, IOE] Source #

data Ui (a :: Type -> Type) b Source #

Instances

Instances details
type DispatchOf Ui Source # 
Instance details

Defined in NanoUI.Monad

data StaticRep Ui Source # 
Instance details

Defined in NanoUI.Monad

runUi :: forall (es :: [Effect]) a. IOE :> es => Context -> Input -> Eff (Ui ': es) a -> Eff es a Source #

uiIO :: forall (es :: [Effect]) a. Ui :> es => IO a -> Eff es a Source #

emit :: forall msg (es :: [Effect]). (Typeable msg, Ui :> es) => msg -> Eff es () Source #

withKey :: forall k (es :: [Effect]) a. (Hashable k, Ui :> es) => k -> Eff es a -> Eff es a Source #

keyed :: forall k (es :: [Effect]) a. (Hashable k, Ui :> es) => k -> Eff es a -> Eff es a Source #

Stable child path from tag. Keys must be unique among siblings in the same scope.

keyedTag :: forall (es :: [Effect]) a. Ui :> es => Word64 -> Eff es a -> Eff es a Source #

scope :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a Source #

withIdFrame :: forall (es :: [Effect]) a. Ui :> es => (IdContext -> (IdContext, IdContext)) -> Eff es a -> Eff es a Source #

nextId :: forall (es :: [Effect]). Ui :> es => Eff es WidgetId Source #

burstNextIds :: forall (es :: [Effect]). Ui :> es => Int -> Eff es () Source #

Issue many widget ids in one IO loop (avoids deep Eff bind chains).

currentId :: forall (es :: [Effect]). Ui :> es => Eff es WidgetId Source #

The id nextId would issue, without consuming it.

askContext :: forall (es :: [Effect]). Ui :> es => Eff es Context Source #

askInput :: forall (es :: [Effect]). Ui :> es => Eff es Input Source #

askDefaultLayout :: forall (es :: [Effect]). Ui :> es => Eff es Layout Source #

withDefaultLayout :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a Source #

askHost :: forall a (es :: [Effect]). (Typeable a, Ui :> es) => Eff es (Maybe a) Source #

uiFontMetrics :: forall (es :: [Effect]). Ui :> es => Eff es FontMetrics Source #

uiTime :: forall (es :: [Effect]). Ui :> es => Eff es Double Source #

Monotonic seconds since some fixed epoch (process boot), as a Double. Use it for time-based animation math inside the UI effect. It stays in Double on purpose: converting wall-clock seconds to Float loses ~3 ms of resolution at 8 h uptime (worse longer), which is coarser than a frame and quantizes animation sweeps into visible steps.

uiTheme :: forall (es :: [Effect]). Ui :> es => Eff es Theme Source #

The theme the view is drawn with where this is called: the context theme as modified by the enclosing styled and disabledWhen scopes.

setUiTheme :: forall (es :: [Effect]). Ui :> es => Theme -> Eff es () Source #

styled :: forall (es :: [Effect]) a. Ui :> es => (Theme -> Theme) -> Eff es a -> Eff es a Source #

Draw a part of the view with a modified theme. Widgets declared inside take their colours, borders and corner radii from it, and styled scopes nest, each modifying the theme of the scope around it:

styled (buttonStyle (cornerRadius 8)) $ do
  styled primary (button "Save")
  button "Cancel"

The modifier runs once per scope per frame. The theme only affects how widgets look, never their layout.

themed :: forall (es :: [Effect]) a. Ui :> es => Theme -> Eff es a -> Eff es a Source #

Draw a part of the view with another theme, whatever the theme around it.

disabledWhen :: forall (es :: [Effect]) a. Ui :> es => Bool -> Eff es a -> Eff es a Source #

Disable every widget declared inside when the condition holds. Disabled widgets keep their place, state and layout, but take no pointer or keyboard input, cannot be focused, and are drawn with disabledTheme.

disabledWhen (T.null name) $ whenM (button "Save") save

uiMousePos :: forall (es :: [Effect]). Ui :> es => Eff es V2 Source #

windowSize :: forall (es :: [Effect]). Ui :> es => Eff es Size Source #

windowWidth :: forall (es :: [Effect]). Ui :> es => Eff es Float Source #

windowHeight :: forall (es :: [Effect]). Ui :> es => Eff es Float Source #

damageWidgetNow :: forall (es :: [Effect]). Ui :> es => WidgetId -> DamageBounds -> Eff es () Source #

damageKeyNow :: forall (es :: [Effect]). Ui :> es => Int -> DamageBounds -> Eff es () Source #

damageRectNow :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es () Source #

damageGroupNow :: forall (es :: [Effect]). Ui :> es => [WidgetId] -> DamageBounds -> Eff es () Source #

damageFullNow :: forall (es :: [Effect]). Ui :> es => Eff es () Source #

data FrameMsg where Source #

Constructors

FrameMsg :: forall a. Typeable a => a -> FrameMsg 

reduceMessages :: (Foldable f, Typeable msg) => (msg -> model -> model) -> model -> f FrameMsg -> model Source #

reduceUpdates :: (Foldable f, Typeable model) => model -> f FrameMsg -> model Source #

whenM :: Monad m => m Bool -> m () -> m () Source #

Monadic variant of when. Runs the second action if the first returns True.

Example:

whenM (button Save) saveDocument

unlessM :: Monad m => m Bool -> m () -> m () Source #

Monadic variant of unless. Runs the second action if the first returns False.

ifM :: Monad m => m Bool -> m a -> m a -> m a Source #

Monadic conditional selection.