| Copyright | (c) 2026 Zachary Churchill |
|---|---|
| License | MIT |
| Maintainer | zacharyachurchill@gmail.com |
| Safe Haskell | None |
| Language | GHC2024 |
NanoUI
Description
A view is a function that runs every frame. Widgets are ordinary calls: each one lays itself out, reads this frame's input, and returns what the user did. There are no widget objects to keep and no callbacks to register.
counter :: NanoUI ()
counter = do
(n, setN) <- useInt 0
row $ do
whenM (button "-") (setN (n - 1))
label (T.pack (show n))
whenM (button "+") (setN (n + 1))
Run a view with a backend: runSdlApp from nano-ui-sdl or runRgfwApp
from nano-ui-rgfw.
Conventions
- Widgets return what you usually need:
Boolfor buttons and menu items, the new value for inputs, and()for text and decoration. - A primed name also returns the widget's
Response, for hover state, geometry, tooltips, and change or submit flags:button',slider'. - Inputs are controlled. Pass the current value and keep the result; a change you do not store is undone on the next frame. Editing state such as the caret, a drag in progress, or an open dropdown stays inside the widget.
- Layout arguments are modifiers, as in
buttonWith (fixedW 120)orcolumnWith (gap 8 . padAll 12). Widgets with more options take a configuration record:textInputConfigured,tabsConfigured.
State
Keep state in local hooks (useInt, useText, useState), in a model you
pass down through the view, or in a reducer: NanoUI.Emit has widgets that
emit messages, and the backends' reducer runners fold them into the model.
Synopsis
- type NanoUI = Eff '[Ui, IOE]
- data Ui (a :: Type -> Type) b
- runUi :: forall (es :: [Effect]) a. IOE :> es => Context -> Input -> Eff (Ui ': es) a -> Eff es a
- runNanoUI :: Context -> Input -> NanoUI a -> IO a
- uiIO :: forall (es :: [Effect]) a. Ui :> es => IO a -> Eff es a
- whenM :: Monad m => m Bool -> m () -> m ()
- unlessM :: Monad m => m Bool -> m () -> m ()
- ifM :: Monad m => m Bool -> m a -> m a -> m a
- windowSize :: forall (es :: [Effect]). Ui :> es => Eff es Size
- windowWidth :: forall (es :: [Effect]). Ui :> es => Eff es Float
- windowHeight :: forall (es :: [Effect]). Ui :> es => Eff es Float
- uiMousePos :: forall (es :: [Effect]). Ui :> es => Eff es V2
- scope :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- keyed :: forall k (es :: [Effect]) a. (Hashable k, Ui :> es) => k -> Eff es a -> Eff es a
- keyedTag :: forall (es :: [Effect]) a. Ui :> es => Word64 -> Eff es a -> Eff es a
- withKey :: forall k (es :: [Effect]) a. (Hashable k, Ui :> es) => k -> Eff es a -> Eff es a
- nextId :: forall (es :: [Effect]). Ui :> es => Eff es WidgetId
- currentId :: forall (es :: [Effect]). Ui :> es => Eff es WidgetId
- burstNextIds :: forall (es :: [Effect]). Ui :> es => Int -> Eff es ()
- newtype WidgetId = WidgetId Word64
- data IdContext
- initialIdContext :: IdContext
- widgetId :: HasCallStack => WidgetId
- hashWidgetId :: WidgetId -> Word64
- mix64 :: Word64 -> Word64 -> Word64
- mixFnv :: Word64 -> Word64 -> Word64
- data Response = Response {
- rawRespId :: !WidgetId
- rawRespRect :: !Rect
- rawRespHovered :: !Bool
- rawRespPressed :: !Bool
- rawRespClicked :: !Bool
- rawRespChanged :: !Bool
- rawRespSubmitted :: !Bool
- rawRespRightPressed :: !Bool
- rawRespRightClicked :: !Bool
- class HasResponse r where
- toResponse :: r -> Response
- respId :: HasResponse r => r -> WidgetId
- respRect :: HasResponse r => r -> Rect
- respHovered :: HasResponse r => r -> Bool
- respPressed :: HasResponse r => r -> Bool
- respClicked :: HasResponse r => r -> Bool
- respChanged :: HasResponse r => r -> Bool
- respSubmitted :: HasResponse r => r -> Bool
- respRightPressed :: HasResponse r => r -> Bool
- respRightClicked :: HasResponse r => r -> Bool
- setChanged :: Bool -> Response -> Response
- setClicked :: Bool -> Response -> Response
- setSubmitted :: Bool -> Response -> Response
- row :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- rowWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a
- column :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- columnWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a
- hstack :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f (Eff es ()) -> Eff es ()
- vstack :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f (Eff es ()) -> Eff es ()
- grid :: forall (es :: [Effect]) a. Ui :> es => Int -> Eff es a -> Eff es a
- gridWith :: forall (es :: [Effect]) a. Ui :> es => Int -> (Layout -> Layout) -> Eff es a -> Eff es a
- panel :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- panelWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a
- card :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- callout :: forall (es :: [Effect]) a. Ui :> es => Color -> Eff es a -> Eff es a
- calloutWith :: forall (es :: [Effect]) a. Ui :> es => Color -> (Layout -> Layout) -> Eff es a -> Eff es a
- toolbar :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- center :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- responsive :: forall (es :: [Effect]) a. Ui :> es => Float -> (Eff es a -> Eff es a) -> (Eff es a -> Eff es a) -> Eff es a -> Eff es a
- responsiveRowCol :: forall (es :: [Effect]) a. Ui :> es => Float -> (Layout -> Layout) -> Eff es a -> Eff es a
- scroll :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- scrollWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a
- scroll2D :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a
- scroll2DWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a
- scrollArea :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es (WidgetId, a)
- scrollArea2D :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es (WidgetId, a)
- separator :: forall (es :: [Effect]). Ui :> es => Eff es ()
- spacer :: forall (es :: [Effect]). Ui :> es => Sizing -> Sizing -> Eff es ()
- flex :: forall (es :: [Effect]). Ui :> es => Eff es ()
- label :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- label' :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Response
- labelWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es ()
- labelWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Response
- heading :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- muted :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- mono :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- danger :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- bold :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- italic :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- underline :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- kv :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es ()
- kvMono :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es ()
- kvBlock :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f (Text, Text) -> Eff es ()
- selectableText :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- selectableText' :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Response
- selectableTextWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es ()
- selectableTextWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Response
- button :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Bool
- button' :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Response
- buttonWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Bool
- buttonWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Response
- menuButton :: forall (es :: [Effect]). Ui :> es => Text -> Bool -> Eff es Bool
- menuButton' :: forall (es :: [Effect]). Ui :> es => Text -> Bool -> Eff es Response
- menuItem :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Bool
- menuItem' :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Response
- menuItemShortcut :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es Bool
- menuItemDisabled :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- menuSeparator :: forall (es :: [Effect]). Ui :> es => Eff es ()
- menuHeader :: forall (es :: [Effect]). Ui :> es => Text -> Eff es ()
- contextMenu :: forall (es :: [Effect]) r a. (Ui :> es, HasResponse r) => r -> Eff es a -> Eff es (Maybe a)
- contextMenuArea :: forall (es :: [Effect]) a b. Ui :> es => (Layout -> Layout) -> Eff es a -> (V2 -> Eff es b) -> Eff es (a, Maybe b)
- useContextMenu :: forall (es :: [Effect]). Ui :> es => Eff es (Bool, V2, V2 -> Eff es (), Eff es ())
- checkbox :: forall (es :: [Effect]). Ui :> es => Text -> Bool -> Eff es Bool
- checkbox' :: forall (es :: [Effect]). Ui :> es => Text -> Bool -> Eff es (Response, Bool)
- toggleSwitch :: forall (es :: [Effect]). Ui :> es => Bool -> Eff es Bool
- toggleSwitch' :: forall (es :: [Effect]). Ui :> es => Bool -> Eff es (Response, Bool)
- toggleSwitchWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Bool -> Eff es Bool
- toggleSwitchWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Bool -> Eff es (Response, Bool)
- radio :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es Int
- radio' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es (Response, Int)
- boundedRadio :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es a
- boundedRadio' :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es (Response, a)
- enumRadio :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es a
- enumRadio' :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es (Response, a)
- select :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es Int
- select' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es (Response, Int)
- selectWith :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => (Layout -> Layout) -> f Text -> Int -> Eff es Int
- selectWith' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => (Layout -> Layout) -> f Text -> Int -> Eff es (Response, Int)
- boundedSelect :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es a
- boundedSelect' :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es (Response, a)
- enumSelect :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es a
- enumSelect' :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es (Response, a)
- slider :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es Float
- slider' :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es (Response, Float)
- sliderWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Eff es Float
- sliderWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Eff es (Response, Float)
- knob :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es Float
- knob' :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es (Response, Float)
- knobWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Float -> Eff es Float
- knobWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Float -> Eff es (Response, Float)
- data TextInputConfig = TextInputConfig {
- ticPlaceholder :: !Text
- ticPassword :: !Bool
- ticLayout :: !Layout
- defaultTextInputConfig :: TextInputConfig
- textInput :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Text
- textInput' :: forall (es :: [Effect]). Ui :> es => Text -> Eff es (Response, Text)
- textInputConfigured :: forall (es :: [Effect]). Ui :> es => TextInputConfig -> Text -> Eff es Text
- textInputConfigured' :: forall (es :: [Effect]). Ui :> es => TextInputConfig -> Text -> Eff es (Response, Text)
- data NumericInputConfig = NumericInputConfig {}
- defaultNumericInputConfig :: NumericInputConfig
- numericInput :: forall (es :: [Effect]). Ui :> es => Double -> Eff es Double
- numericInput' :: forall (es :: [Effect]). Ui :> es => Double -> Eff es (Response, Double)
- numericInputConfigured :: forall (es :: [Effect]). Ui :> es => NumericInputConfig -> Double -> Eff es Double
- numericInputConfigured' :: forall (es :: [Effect]). Ui :> es => NumericInputConfig -> Double -> Eff es (Response, Double)
- data SearchFieldConfig = SearchFieldConfig {
- sfcPlaceholder :: !Text
- sfcDebounceMs :: !Float
- sfcLayout :: !Layout
- defaultSearchFieldConfig :: SearchFieldConfig
- searchField :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es Text
- searchField' :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es (Response, Text)
- searchFieldConfigured :: forall (es :: [Effect]). Ui :> es => SearchFieldConfig -> Text -> Eff es Text
- searchFieldConfigured' :: forall (es :: [Effect]). Ui :> es => SearchFieldConfig -> Text -> Eff es (Response, Text)
- comboBox :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f Text -> Text -> Eff es Text
- comboBox' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f Text -> Text -> Eff es (Response, Text)
- textArea :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Text
- textArea' :: forall (es :: [Effect]). Ui :> es => Text -> Eff es (Response, Text)
- textAreaWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Text
- textAreaWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es (Response, Text)
- colorPicker :: forall (es :: [Effect]). Ui :> es => Color -> Eff es Color
- colorPicker' :: forall (es :: [Effect]). Ui :> es => Color -> Eff es (Response, Color)
- colorPickerRGBA :: forall (es :: [Effect]). Ui :> es => Color -> Eff es Color
- colorPickerRGBA' :: forall (es :: [Effect]). Ui :> es => Color -> Eff es (Response, Color)
- colorToHex :: Color -> Text
- colorToHexA :: Color -> Text
- colorFromHex :: Text -> Maybe Color
- data TextCommand
- data TextMotion
- data Cursor = Cursor {}
- runTextCommand :: forall (es :: [Effect]). Ui :> es => WidgetId -> TextCommand -> Eff es ()
- textCanUndo :: forall (es :: [Effect]). Ui :> es => WidgetId -> Eff es Bool
- textCanRedo :: forall (es :: [Effect]). Ui :> es => WidgetId -> Eff es Bool
- data Tab a body = Tab {}
- data TabStyle
- data TabOrientation
- data TabResponse a = TabResponse {
- tabResponse :: !Response
- tabClosed :: !(Maybe a)
- tabActive :: !a
- data TabsConfig = TabsConfig {}
- defaultTabsConfig :: TabsConfig
- tab :: a -> Text -> body -> Tab a body
- closableTab :: a -> Text -> body -> Tab a body
- tabs :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => a -> f (Tab a (Eff es ())) -> Eff es a
- tabs' :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => a -> f (Tab a (Eff es ())) -> Eff es (TabResponse a)
- tabsConfigured :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a (Eff es ())) -> Eff es a
- tabsConfigured' :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a (Eff es ())) -> Eff es (TabResponse a)
- tabBar :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => a -> f (Tab a body) -> Eff es a
- tabBar' :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => a -> f (Tab a body) -> Eff es (TabResponse a)
- tabBarConfigured :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a body) -> Eff es a
- tabBarConfigured' :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a body) -> Eff es (TabResponse a)
- data TreeItem = TreeItem {
- treeItemLabel :: !Text
- treeItemChildren :: ![TreeItem]
- tree :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f TreeItem -> Int -> Eff es Int
- tree' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f TreeItem -> Int -> Eff es (Response, Int)
- data SortDir
- data SortCol = SortCol {
- sortColIndex :: !Int
- sortColDir :: !SortDir
- data ColSize
- data TableConfig = TableConfig {
- tableFreezeCols :: !Int
- tableFreezeRows :: !Int
- tableColSizes :: ![ColSize]
- tableHidden :: !IntSet
- data TableResponse = TableResponse {
- tableWidgetResponse :: !Response
- tableSort :: !SortCol
- tableColOrder :: ![Int]
- tableHiddenCols :: !IntSet
- defaultTableConfig :: TableConfig
- table :: forall f (es :: [Effect]) row. (Foldable f, Ui :> es) => Text -> Colonnade Headed row Text -> f row -> SortCol -> Eff es TableResponse
- tableWith :: forall f (es :: [Effect]) row. (Foldable f, Ui :> es) => (Layout -> Layout) -> Text -> Colonnade Headed row Text -> f row -> SortCol -> Eff es TableResponse
- tableConfigured :: forall f (es :: [Effect]) row. (Foldable f, Ui :> es) => TableConfig -> (Layout -> Layout) -> Text -> Colonnade Headed row Text -> f row -> SortCol -> Eff es TableResponse
- simpleTable :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => [Text] -> f [Text] -> Eff es TableResponse
- useTableSort :: forall (es :: [Effect]). Ui :> es => SortCol -> Eff es (SortCol, SortCol -> Eff es ())
- tableHiddenIndices :: TableResponse -> [Int]
- sortRows :: Foldable f => Colonnade Headed row Text -> SortCol -> f row -> [row]
- data Colonnade (h :: Type -> Type) a c
- newtype Headed a = Headed {
- getHeaded :: a
- headed :: c -> (a -> c) -> Colonnade Headed a c
- headless :: (a -> c) -> Colonnade Headless a c
- modal :: forall (es :: [Effect]) a. Ui :> es => Bool -> Text -> Eff es a -> Eff es (Response, Maybe a)
- window :: forall (es :: [Effect]) a. Ui :> es => Bool -> Text -> Eff es a -> Eff es (Response, Maybe a)
- data PopupAnchor
- = AnchorPoint !V2
- | AnchorRect !Rect
- data PopupPlacement
- data PopupConfig = PopupConfig {
- cfgAnchor :: !PopupAnchor
- cfgPlacement :: !PopupPlacement
- cfgDismissable :: !Bool
- cfgOffset :: !Float
- defaultPopupConfig :: PopupAnchor -> PopupConfig
- popup :: forall (es :: [Effect]) a. Ui :> es => Bool -> PopupConfig -> Eff es a -> Eff es (Response, Maybe a)
- popupWith :: forall (es :: [Effect]) a. Ui :> es => Bool -> PopupConfig -> (Layout -> Layout) -> Eff es a -> Eff es (Response, Maybe a)
- tooltip :: forall (es :: [Effect]) r. (Ui :> es, HasResponse r) => r -> Text -> Eff es ()
- tooltipAt :: forall (es :: [Effect]) r. (Ui :> es, HasResponse r) => PopupPlacement -> r -> Text -> Eff es ()
- tooltipWidget :: forall (es :: [Effect]) r a. (Ui :> es, HasResponse r) => r -> Eff es a -> Eff es (Maybe a)
- withTooltip :: forall (es :: [Effect]) a b. Ui :> es => Eff es a -> Eff es b -> Eff es (a, Maybe b)
- data PaneGridConfig (es :: [Effect]) = PaneGridConfig {}
- defaultPaneGridConfig :: forall (es :: [Effect]). PaneGridConfig es
- data PaneGridCtx (es :: [Effect]) = PaneGridCtx {
- pgcPaneId :: !Word64
- pgcRect :: !Rect
- pgcMaximized :: !Bool
- pgcDragging :: !Bool
- pgcDndActive :: !Bool
- pgcSplit :: !(GridAxis -> Eff es Word64)
- pgcClose :: !(Eff es ())
- pgcMaximize :: !(Eff es ())
- pgcRestore :: !(Eff es ())
- data PaneView = PaneView {
- pvTitle :: !Text
- pvDraggable :: !Bool
- pvDragPick :: !(Maybe Rect)
- data PaneGridResponse = PaneGridResponse {
- pgrChanged :: !Bool
- pgrPaneCount :: !Int
- pgrPanes :: ![Word64]
- pgrFocusedPane :: !Word64
- pgrMaximizedPane :: !Word64
- data GridAxis
- paneGrid :: forall (es :: [Effect]). Ui :> es => PaneGridConfig es -> Eff es PaneGridResponse
- progressBar :: forall (es :: [Effect]). Ui :> es => Float -> Eff es ()
- progressBar' :: forall (es :: [Effect]). Ui :> es => Float -> Eff es Response
- progressBarWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es ()
- progressBarWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es Response
- circularProgress :: forall (es :: [Effect]). Ui :> es => Float -> Eff es ()
- circularProgress' :: forall (es :: [Effect]). Ui :> es => Float -> Eff es Response
- circularProgressWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es ()
- circularProgressWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es Response
- spinner :: forall (es :: [Effect]). Ui :> es => Eff es ()
- spinner' :: forall (es :: [Effect]). Ui :> es => Eff es Response
- spinnerWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Eff es ()
- spinnerWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Eff es Response
- data Inline
- inlineText :: Text -> Inline
- inlineWith :: (Layout -> Layout) -> Text -> Inline
- restyle :: (Layout -> Layout) -> Inline -> Inline
- strong :: Text -> Inline
- emphasis :: Text -> Inline
- inlineCode :: Text -> Inline
- hyperlink :: Text -> Text -> Inline
- richText :: forall (es :: [Effect]). Ui :> es => [Inline] -> Eff es (Maybe Text)
- richText' :: forall (es :: [Effect]). Ui :> es => [Inline] -> Eff es (Response, Maybe Text)
- richTextWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> [Inline] -> Eff es (Maybe Text)
- richTextWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> [Inline] -> Eff es (Response, Maybe Text)
- sparkline :: forall (es :: [Effect]). Ui :> es => [Float] -> Eff es ()
- sparkline' :: forall (es :: [Effect]). Ui :> es => [Float] -> Eff es Response
- sparklineWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> [Float] -> Eff es ()
- sparklineWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> [Float] -> Eff es Response
- newtype ImageId = ImageId {}
- image :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> ImageId -> Eff es ()
- image' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> ImageId -> Eff es Response
- freshImageId :: forall (es :: [Effect]). Ui :> es => Eff es ImageId
- registerImageRgba :: forall (es :: [Effect]). Ui :> es => ImageId -> Int -> Int -> ByteString -> Eff es Bool
- data Svg
- parseSvg :: Text -> Either String Svg
- loadSvg :: FilePath -> IO (Either String Svg)
- svgIcon :: forall (es :: [Effect]). Ui :> es => Float -> Svg -> Eff es ()
- svgIconWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Svg -> Eff es ()
- svgIconWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Svg -> Eff es Response
- svgSize :: Svg -> (Float, Float)
- box :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Color -> Eff es ()
- drawing :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> (Rect -> SmallArray DrawOp) -> Eff es Response
- drawingVersioned :: forall (es :: [Effect]). Ui :> es => Int -> (Layout -> Layout) -> (Rect -> SmallArray DrawOp) -> Eff es Response
- drawingCached :: forall (es :: [Effect]). Ui :> es => Double -> Double -> Float -> Int -> (Layout -> Layout) -> IO Layout -> DrawingBuild -> Eff es Response
- data DrawOp
- = FillRect !Rect !Color
- | FillRoundedRect !Rect !Float !Color
- | FillTriangle !Float !Float !Float !Float !Float !Float !Color
- | FillCircle !Float !Float !Float !Color
- | Stroke !Float !Float !Float !Float !Float !Color
- | StrokeRoundedRect !Rect !Float !Float !Color
- | StrokeCircle !Float !Float !Float !Float !Color
- | StrokeLineAA !Float !Float !Float !Float !Float !Color
- | FillQuadGradient !Rect !Color !Color !Color !Color
- | DrawImageRect !Rect !Int !Float !Float !Float !Float !Color
- | DrawText !Float !Float !Float !Float !Text !Color
- | DrawTextStyled !Float !Float !TextFont !Text !Color
- data TextFont = TextFont {}
- defaultTextFont :: TextFont
- type DrawingBuild = Rect -> SmallArray DrawOp
- drawTextBox :: FontMetrics -> Float -> Float -> Float -> Float -> Text -> Rect
- shiftDrawOp :: Float -> Float -> DrawOp -> DrawOp
- data CustomWidgetSpec a = CustomWidgetSpec {
- widgetLayout :: !Layout
- widgetMeasure :: !(Maybe CustomMeasureFn)
- widgetDraw :: !CustomDrawBuild
- widgetContent :: !Int
- widgetCursor :: !(Maybe (CustomDrawContext -> UiCursorKind))
- widgetFocusable :: !Bool
- widgetDamageSlop :: !Float
- widgetInteract :: !(Response -> CustomDrawContext -> Input -> (Response, a))
- defaultCustomWidgetSpec :: CustomWidgetSpec ()
- customWidget :: forall (es :: [Effect]) a. Ui :> es => CustomWidgetSpec a -> Eff es (Response, a)
- customWidgetWithId :: forall (es :: [Effect]) a. Ui :> es => WidgetId -> CustomWidgetSpec a -> Eff es (Response, a)
- contentKey :: [Float] -> Int
- data CustomDrawContext = CustomDrawContext {
- cdcHovered :: !Bool
- cdcPressed :: !Bool
- cdcFocused :: !Bool
- cdcActive :: !Bool
- cdcDisabled :: !Bool
- cdcTheme :: !Theme
- cdcFont :: !FontMetrics
- type CustomMeasureFn = FontMetrics -> (Float, Float) -> (Float, Float)
- type CustomDrawBuild = CustomDrawContext -> Rect -> SmallArray DrawOp
- data CanvasM a
- runCanvas :: CanvasM a -> SmallArray DrawOp
- canvas :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> (Rect -> CanvasM ()) -> Eff es Response
- drawRect :: Rect -> Color -> CanvasM ()
- drawRoundedRect :: Rect -> Float -> Color -> CanvasM ()
- drawCircle :: V2 -> Float -> Color -> CanvasM ()
- drawStroke :: V2 -> V2 -> Float -> Color -> CanvasM ()
- drawStrokeRoundedRect :: Rect -> Float -> Float -> Color -> CanvasM ()
- drawStrokeCircle :: V2 -> Float -> Float -> Color -> CanvasM ()
- drawStrokeAA :: V2 -> V2 -> Float -> Color -> CanvasM ()
- drawQuadGradient :: Rect -> Color -> Color -> Color -> Color -> CanvasM ()
- drawLinearGradientH :: Rect -> Color -> Color -> CanvasM ()
- drawLinearGradientV :: Rect -> Color -> Color -> CanvasM ()
- drawImage :: Rect -> ImageId -> Color -> CanvasM ()
- drawImageUV :: Rect -> ImageId -> Float -> Float -> Float -> Float -> Color -> CanvasM ()
- drawText :: V2 -> AlignX -> AlignY -> Text -> Color -> CanvasM ()
- useDrag2D :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es Drag2D
- data Drag2D = Drag2D {
- dragPosition :: !V2
- dragActive :: !Bool
- dragDelta :: !V2
- useWheelDelta :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es (Float, Float)
- data DropType
- data DropEvent = DropEvent {
- dropEventType :: !DropType
- dropEventPos :: !(Maybe V2)
- dropEventData :: !Text
- emptyDropEvents :: SmallArray DropEvent
- data DropTarget = DropTarget {
- dropHovered :: !Bool
- dropReceived :: !Bool
- dropFiles :: ![Text]
- dropTexts :: ![Text]
- dropPosition :: !(Maybe V2)
- useDrop :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es DropTarget
- dropZone :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es (a, Response, DropTarget)
- useState :: forall a (es :: [Effect]). (Typeable a, Eq a, Ui :> es) => a -> Eff es (a, a -> Eff es ())
- useFlag :: forall (es :: [Effect]). Ui :> es => Bool -> Eff es (Bool, Bool -> Eff es ())
- useToggle :: forall (es :: [Effect]). Ui :> es => Bool -> Eff es (Bool, Eff es ())
- useInt :: forall (es :: [Effect]). Ui :> es => Int -> Eff es (Int, Int -> Eff es ())
- useFloat :: forall (es :: [Effect]). Ui :> es => Float -> Eff es (Float, Float -> Eff es ())
- useEnum :: forall a (es :: [Effect]). (Enum a, Ui :> es) => a -> Eff es (a, a -> Eff es ())
- useText :: forall (es :: [Effect]). Ui :> es => Text -> Eff es (Text, Text -> Eff es ())
- data ScrollTuning = ScrollTuning {}
- defaultScrollTuning :: ScrollTuning
- getScrollTuning :: Context -> IO ScrollTuning
- setScrollTuning :: Context -> ScrollTuning -> IO ()
- getScrollStep :: Context -> WidgetId -> IO Float
- setScrollStep :: Context -> WidgetId -> Float -> IO ()
- data ScrollMetrics = ScrollMetrics {
- scrollViewport :: !Rect
- scrollRange :: !V2
- scrollOffset :: !V2
- scrollAxes :: !ScrollAxes
- data ScrollAxes
- getScrollMetrics :: Context -> WidgetId -> IO (Maybe ScrollMetrics)
- data ScrollBehavior
- data ScrollAlign
- scrollTo :: Context -> WidgetId -> V2 -> ScrollBehavior -> IO ()
- scrollBy :: Context -> WidgetId -> V2 -> ScrollBehavior -> IO ()
- scrollPages :: Context -> WidgetId -> V2 -> ScrollBehavior -> IO ()
- scrollToStart :: Context -> WidgetId -> ScrollBehavior -> IO ()
- scrollToEnd :: Context -> WidgetId -> ScrollBehavior -> IO ()
- scrollIntoView :: Context -> WidgetId -> WidgetId -> ScrollAlign -> ScrollBehavior -> IO ()
- scrollRectIntoView :: Context -> WidgetId -> Rect -> ScrollAlign -> ScrollBehavior -> IO ()
- scrollGliding :: Context -> WidgetId -> IO Bool
- getScrollOffset :: Context -> WidgetId -> IO Float
- setScrollOffset :: Context -> WidgetId -> Float -> IO ()
- getScrollOffset2D :: Context -> WidgetId -> IO V2
- setScrollOffset2D :: Context -> WidgetId -> V2 -> IO ()
- data Transition
- animate :: forall (es :: [Effect]). Ui :> es => Transition -> Float -> Float -> Eff es Float
- animateTo :: forall (es :: [Effect]). Ui :> es => Transition -> Float -> Eff es Float
- animateToA :: forall a (es :: [Effect]). (Animatable a, Ui :> es) => Transition -> a -> Eff es a
- pulse :: forall (es :: [Effect]). Ui :> es => Float -> Eff es Float
- keepAnimating :: forall r (es :: [Effect]). (HasResponse r, Ui :> es) => r -> Eff es ()
- class Animatable a where
- toComponents :: a -> [Float]
- fromComponents :: [Float] -> a
- data Ease
- applyEase :: Ease -> Float -> Float
- data SpringParams = SpringParams {
- springStiffness :: !Float
- springDamping :: !Float
- springMass :: !Float
- presetBouncy :: SpringParams
- presetSmooth :: SpringParams
- presetStiff :: SpringParams
- data Layout = Layout {
- layoutDirection :: !Direction
- layoutWidth :: !Sizing
- layoutHeight :: !Sizing
- layoutPadding :: !Padding
- layoutGap :: !Float
- layoutAlignX :: !AlignX
- layoutAlignY :: !AlignY
- layoutMinW :: !Float
- layoutMinH :: !Float
- layoutMaxW :: !Float
- layoutMaxH :: !Float
- layoutFontVariant :: !FontVariant
- layoutGridCols :: !Int
- layoutGridMinColW :: !Float
- layoutFontSize :: !Float
- layoutFontColor :: !(Maybe Color)
- layoutFontWeight :: !FontWeight
- layoutFontStyle :: !FontStyle
- layoutTextDecoration :: !TextDecoration
- type LayoutModifier = Layout -> Layout
- data Sizing
- data Direction
- data AlignX
- data AlignY
- data Padding = Padding {}
- defaultLayout :: Layout
- askDefaultLayout :: forall (es :: [Effect]). Ui :> es => Eff es Layout
- withDefaultLayout :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a
- padAll :: Float -> Layout -> Layout
- padXY :: Float -> Float -> Layout -> Layout
- gap :: Float -> Layout -> Layout
- fillW :: Layout -> Layout
- fillH :: Layout -> Layout
- grow :: Layout -> Layout
- minW :: Float -> Layout -> Layout
- maxW :: Float -> Layout -> Layout
- fixedW :: Float -> Layout -> Layout
- minH :: Float -> Layout -> Layout
- maxH :: Float -> Layout -> Layout
- fixedH :: Float -> Layout -> Layout
- fixedWH :: Float -> Float -> Layout -> Layout
- alignMid :: Layout -> Layout
- alignEnd :: Layout -> Layout
- alignStart :: Layout -> Layout
- alignCenter :: Layout -> Layout
- alignTop :: Layout -> Layout
- alignBottom :: Layout -> Layout
- alignBaseline :: Layout -> Layout
- tight :: Layout -> Layout
- percent :: Float -> Layout -> Layout
- gridMinColW :: Float -> Layout -> Layout
- gridCols :: Int -> Layout -> Layout
- fixedAspectW :: Float -> Float -> Layout -> Layout
- fixedAspectH :: Float -> Float -> Layout -> Layout
- data FontVariant
- data FontWeight
- data FontStyle
- data TextDecoration
- fontRegular :: Layout -> Layout
- fontHeading :: Layout -> Layout
- fontMuted :: Layout -> Layout
- fontMono :: Layout -> Layout
- fontDanger :: Layout -> Layout
- fontSize :: Float -> Layout -> Layout
- fontSizeScale :: Float -> Layout -> Layout
- fontColor :: Color -> Layout -> Layout
- fontWeight :: FontWeight -> Layout -> Layout
- fontBold :: Layout -> Layout
- fontLight :: Layout -> Layout
- fontMedium :: Layout -> Layout
- fontSemiBold :: Layout -> Layout
- fontExtraBold :: Layout -> Layout
- fontBlack :: Layout -> Layout
- fontStyle :: FontStyle -> Layout -> Layout
- fontItalic :: Layout -> Layout
- fontOblique :: Layout -> Layout
- textDecoration :: TextDecoration -> Layout -> Layout
- fontUnderline :: Layout -> Layout
- fontStrike :: Layout -> Layout
- styled :: forall (es :: [Effect]) a. Ui :> es => (Theme -> Theme) -> Eff es a -> Eff es a
- themed :: forall (es :: [Effect]) a. Ui :> es => Theme -> Eff es a -> Eff es a
- disabledWhen :: forall (es :: [Effect]) a. Ui :> es => Bool -> Eff es a -> Eff es a
- uiTheme :: forall (es :: [Effect]). Ui :> es => Eff es Theme
- background :: Color -> Style -> Style
- foreground :: Color -> Style -> Style
- borderColor :: Color -> Style -> Style
- borderWidth :: Float -> Style -> Style
- cornerRadius :: Float -> Style -> Style
- hoverBackground :: Color -> Style -> Style
- pressBackground :: Color -> Style -> Style
- fillColor :: Color -> Style -> Style
- buttonStyle :: (Style -> Style) -> Theme -> Theme
- inputStyle :: (Style -> Style) -> Theme -> Theme
- panelStyle :: (Style -> Style) -> Theme -> Theme
- windowStyle :: (Style -> Style) -> Theme -> Theme
- everyStyle :: (Style -> Style) -> Theme -> Theme
- accentColor :: Color -> Theme -> Theme
- textColor :: Color -> Theme -> Theme
- mutedColor :: Color -> Theme -> Theme
- linkColor :: Color -> Theme -> Theme
- selectionColor :: Color -> Theme -> Theme
- windowColor :: Color -> Theme -> Theme
- rounded :: Float -> Theme -> Theme
- primary :: Theme -> Theme
- destructive :: Theme -> Theme
- success :: Theme -> Theme
- subtle :: Theme -> Theme
- tinted :: (Theme -> Color) -> Theme -> Theme
- readableOn :: Theme -> Color -> Color
- disabledTheme :: Theme -> Theme
- data Theme = Theme {
- themeWindow :: !Color
- themePanel :: !Style
- themeFloatingWindow :: !Style
- themeButton :: !Style
- themeInput :: !Style
- themeSeparator :: !Color
- themeAccent :: !Color
- themeMuted :: !Color
- themeRed :: !Color
- themeOrange :: !Color
- themeYellow :: !Color
- themeGreen :: !Color
- themePurple :: !Color
- themeOverlayDim :: !Color
- themeOnAccent :: !Color
- themeSelection :: !Color
- themeFocusRing :: !Color
- themeLink :: !Color
- themeShadow :: !Color
- themeDisabledFade :: !Float
- data Style = Style {
- styleBg :: !Color
- styleFg :: !Color
- styleBorder :: !Color
- styleBorderWidth :: !Float
- styleCornerRadius :: !Float
- styleHoverBg :: !Color
- styleActiveBg :: !Color
- defaultTheme :: Theme
- tomorrowNightMinDarkTheme :: Theme
- tomorrowMinLightTheme :: Theme
- tomorrowMidnightMinDarkTheme :: Theme
- data Base16 = Base16 {}
- themeFromBase16 :: Base16 -> Theme
- themeFromBase16Dark :: Base16 -> Theme
- themeFromBase16Light :: Base16 -> Theme
- base16TomorrowNight :: Base16
- base16TomorrowLight :: Base16
- withTheme :: Context -> Theme -> IO Context
- setTheme :: Context -> Theme -> IO ()
- getTheme :: Context -> IO Theme
- setUiTheme :: forall (es :: [Effect]). Ui :> es => Theme -> Eff es ()
- themeSeries :: Theme -> [Color]
- scrollBarTrackColor :: Style -> Theme -> Color
- scrollBarThumbColor :: Style -> Theme -> Color
- data V2 = V2 {}
- data Rect = Rect {}
- data Size = Size {}
- newtype Color = Color Word32
- colorRGBA :: Word8 -> Word8 -> Word8 -> Word8 -> Color
- colorToWord32 :: Color -> Word32
- colorLuminance :: Color -> Double
- colorR :: Color -> Word8
- colorG :: Color -> Word8
- colorB :: Color -> Word8
- colorA :: Color -> Word8
- lerpColor :: Color -> Color -> Float -> Color
- contrastRatio :: Color -> Color -> Double
- rectContains :: Rect -> V2 -> Bool
- rectInflate :: Float -> Rect -> Rect
- rectIntersect :: Rect -> Rect -> Maybe Rect
- rectUnion :: Rect -> Rect -> Rect
- v2Add :: V2 -> V2 -> V2
- v2Sub :: V2 -> V2 -> V2
- onGrid :: Float -> Float -> Float
- roundHalfUp :: Float -> Int
- data Input = Input {
- inputMousePos :: !V2
- inputMouseDown :: !Bool
- inputMousePressed :: !Bool
- inputMouseReleased :: !Bool
- inputMouseRightDown :: !Bool
- inputMouseRightPressed :: !Bool
- inputMouseRightReleased :: !Bool
- inputMouseClicks :: !Int
- inputScroll :: !V2
- inputKeys :: SmallArray Key
- inputChars :: !Text
- inputModifiers :: !Modifiers
- inputWindowSize :: !Size
- inputDeltaTime :: !Float
- inputDrops :: SmallArray DropEvent
- inputWindowRedraw :: !Bool
- data Key
- data Modifiers = Modifiers {}
- emptyInput :: Input
- inputInteracted :: Input -> Input -> Bool
- inputPointerHeld :: Input -> Bool
- appendInputKey :: Key -> SmallArray Key -> SmallArray Key
- appendDropEvent :: DropEvent -> SmallArray DropEvent -> SmallArray DropEvent
- emptyInputKeys :: SmallArray Key
- inputKeysElem :: Key -> SmallArray Key -> Bool
- inputKeysFromList :: [Key] -> SmallArray Key
- inputKeysNull :: SmallArray Key -> Bool
- foldInputKeys :: (a -> Key -> a) -> a -> SmallArray Key -> a
- data Damage
- data DamageBounds
- defaultDamageSlop :: Float
- sliderDamageSlop :: Float
- haloDamageSlop :: Float
- resolveDamageRect :: DamageBounds -> Rect -> Rect
- damageWidgetNow :: forall (es :: [Effect]). Ui :> es => WidgetId -> DamageBounds -> Eff es ()
- damageKeyNow :: forall (es :: [Effect]). Ui :> es => Int -> DamageBounds -> Eff es ()
- damageRectNow :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es ()
- damageGroupNow :: forall (es :: [Effect]). Ui :> es => [WidgetId] -> DamageBounds -> Eff es ()
- damageFullNow :: forall (es :: [Effect]). Ui :> es => Eff es ()
- data FontMetrics = FontMetrics {}
- data FontBackend = FontBackend {
- fbPrepare :: Text -> IO FontMetrics
- fbDrawShaped :: Text -> IO (Maybe ShapedGlyphs)
- fbDrawGlyph :: Char -> IO (Maybe GlyphQuad)
- prepareFontMetrics :: FontMetrics -> Text -> IO FontMetrics
- prepareFontMetricsMany :: FontMetrics -> [Text] -> IO FontMetrics
- measureTextIO :: FontMetrics -> Text -> IO (Float, Float)
- lineWidthIO :: FontMetrics -> Text -> IO Float
- lineWidth :: FontMetrics -> Text -> Float
- drawShaped :: FontMetrics -> Text -> IO (Maybe ShapedGlyphs)
- drawGlyph :: FontMetrics -> Char -> IO (Maybe GlyphQuad)
- data GlyphQuad = GlyphQuad {}
- data ShapedText = ShapedText {}
- newtype ShapedGlyphs = ShapedGlyphs (PrimArray Float)
- scaleFontMetrics :: Float -> FontMetrics -> FontMetrics
- monospaceMetrics :: Float -> FontMetrics
- uiFontMetrics :: forall (es :: [Effect]). Ui :> es => Eff es FontMetrics
- widgetContentInset :: FontMetrics -> (Float, Float)
- widgetPadding :: FontMetrics -> (Float, Float)
- treeItemPadding :: FontMetrics -> (Float, Float)
- data ScrollBarSlot
- scrollBarGutter :: ScrollBarSlot -> Float -> Float
- scrollBarWidth :: Float
- windowPad :: Padding
- windowMargin :: Float
- data Compact a
- compactHost :: Typeable a => Context -> a -> IO (Compact a)
- askCompact :: forall a (es :: [Effect]). (Typeable a, Ui :> es) => Eff es (Maybe a)
Views
data Ui (a :: Type -> Type) b Source #
Instances
| type DispatchOf Ui Source # | |
Defined in NanoUI.Monad | |
| data StaticRep Ui Source # | |
runUi :: forall (es :: [Effect]) a. IOE :> es => Context -> Input -> Eff (Ui ': es) a -> Eff es a Source #
Widget identity
Every widget and hook takes the next WidgetId in its container:
ids count up in call order among siblings, and a container starts a
new count for its children. Widget state is stored under that id, so
the same widgets and hooks must run in the same order every frame.
A widget that runs on some frames and not others moves the ids of the
siblings after it. Put the conditional part inside scope, which takes
one id whether or not its body adds anything. For a list whose items
are added, removed or reordered, run each item under withKey (or
keyed) with a key unique among its siblings, so the item's state
follows its key instead of its position.
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.
withKey :: forall k (es :: [Effect]) a. (Hashable k, Ui :> es) => k -> Eff es a -> Eff es a Source #
currentId :: forall (es :: [Effect]). Ui :> es => Eff es WidgetId Source #
The id nextId would issue, without consuming it.
burstNextIds :: forall (es :: [Effect]). Ui :> es => Int -> Eff es () Source #
Issue many widget ids in one IO loop (avoids deep Eff bind chains).
Instances
| Eq WidgetId Source # | |
| Ord WidgetId Source # | |
Defined in NanoUI.Id | |
| Show WidgetId Source # | |
| Hashable WidgetId Source # | |
| Prim WidgetId Source # | |
Defined in NanoUI.Id Methods sizeOfType# :: Proxy WidgetId -> Int# # alignmentOfType# :: Proxy WidgetId -> Int# # alignment# :: WidgetId -> Int# # indexByteArray# :: ByteArray# -> Int# -> WidgetId # readByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, WidgetId #) # writeByteArray# :: MutableByteArray# s -> Int# -> WidgetId -> State# s -> State# s # setByteArray# :: MutableByteArray# s -> Int# -> Int# -> WidgetId -> State# s -> State# s # indexOffAddr# :: Addr# -> Int# -> WidgetId # readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, WidgetId #) # writeOffAddr# :: Addr# -> Int# -> WidgetId -> State# s -> State# s # setOffAddr# :: Addr# -> Int# -> Int# -> WidgetId -> State# s -> State# s # | |
widgetId :: HasCallStack => WidgetId Source #
hashWidgetId :: WidgetId -> Word64 Source #
Responses
Constructors
| Response | |
Fields
| |
class HasResponse r where Source #
Anything that carries a widget Response (composite widget results such
as TabResponse). The resp* accessors work on all of them.
Methods
toResponse :: r -> Response Source #
Instances
| HasResponse Response Source # | |
Defined in NanoUI.Widgets.Node Methods toResponse :: Response -> Response Source # | |
| HasResponse TableResponse Source # | |
Defined in NanoUI.Widgets.Table Methods toResponse :: TableResponse -> Response Source # | |
| HasResponse (TabResponse a) Source # | |
Defined in NanoUI.Widgets.Tabs Methods toResponse :: TabResponse a -> Response Source # | |
respId :: HasResponse r => r -> WidgetId Source #
respRect :: HasResponse r => r -> Rect Source #
respHovered :: HasResponse r => r -> Bool Source #
respPressed :: HasResponse r => r -> Bool Source #
respClicked :: HasResponse r => r -> Bool Source #
respChanged :: HasResponse r => r -> Bool Source #
respSubmitted :: HasResponse r => r -> Bool Source #
respRightPressed :: HasResponse r => r -> Bool Source #
respRightClicked :: HasResponse r => r -> Bool Source #
Containers
rowWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a Source #
columnWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a Source #
hstack :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f (Eff es ()) -> Eff es () Source #
Run a collection of widgets side by side, as in hstack (map label names).
vstack :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f (Eff es ()) -> Eff es () Source #
Run a collection of widgets top to bottom.
gridWith :: forall (es :: [Effect]) a. Ui :> es => Int -> (Layout -> Layout) -> Eff es a -> Eff es a Source #
panelWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a Source #
calloutWith :: forall (es :: [Effect]) a. Ui :> es => Color -> (Layout -> Layout) -> Eff es a -> Eff es a Source #
A panel tinted with col: a border in it and a faint wash of it over the
panel colour. The tint applies to the callout's own panel and to panels
nested in it.
responsive :: forall (es :: [Effect]) a. Ui :> es => Float -> (Eff es a -> Eff es a) -> (Eff es a -> Eff es a) -> Eff es a -> Eff es a Source #
Choose between two container builders based on window width.
responsiveRowCol :: forall (es :: [Effect]) a. Ui :> es => Float -> (Layout -> Layout) -> Eff es a -> Eff es a Source #
A row while the window is at least breakpoint wide, a column below it.
scrollWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a Source #
scroll2D :: forall (es :: [Effect]) a. Ui :> es => Eff es a -> Eff es a Source #
Scroll container on both axes.
scroll2DWith :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a Source #
scrollArea :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es (WidgetId, a) Source #
scrollWith that also returns the container's widget id, which keys its
scroll offset.
scrollArea2D :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es (WidgetId, a) Source #
scroll2DWith that also returns the container's widget id.
separator :: forall (es :: [Effect]). Ui :> es => Eff es () Source #
A one-pixel rule: horizontal in a column, vertical in a row.
spacer :: forall (es :: [Effect]). Ui :> es => Sizing -> Sizing -> Eff es () Source #
Empty space with the given sizing on each axis.
flex :: forall (es :: [Effect]). Ui :> es => Eff es () Source #
Takes up the remaining space along the parent's direction.
Text
label :: forall (es :: [Effect]). Ui :> es => Text -> Eff es () Source #
A line of text. Newlines start new lines.
labelWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es () Source #
label with a layout modifier, for example labelWith fontMono.
labelWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Response Source #
kv :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es () Source #
Key/value row: a muted key on the left, the value right-aligned. Trailing whitespace in the value is dropped.
kvMono :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es () Source #
Key/value row with a monospace value.
kvBlock :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f (Text, Text) -> Eff es () Source #
Key/value pairs as one monospace block with the keys padded to a column.
selectableText :: forall (es :: [Effect]). Ui :> es => Text -> Eff es () Source #
Read-only text that can be selected with the mouse and copied with Ctrl+C.
selectableTextWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es () Source #
selectableTextWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Response Source #
Buttons and menus
buttonWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Bool Source #
buttonWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Response Source #
menuButton :: forall (es :: [Effect]). Ui :> es => Text -> Bool -> Eff es Bool Source #
Menu-bar title: a flat, label-sized button. open tints the title while
its drop-down is showing. True on the frame it is clicked.
menuButton' :: forall (es :: [Effect]). Ui :> es => Text -> Bool -> Eff es Response Source #
menuButton returning its Response, whose rect anchors the drop-down.
menuItem :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Bool Source #
Menu row. True on the frame it is clicked.
whenM (menuItem "Open...") openFile
menuItemShortcut :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es Bool Source #
Menu row with a shortcut hint after the label. The hint is only text; handle the key itself elsewhere.
whenM (menuItemShortcut Save "Ctrl+S") saveFile
menuItemDisabled :: forall (es :: [Effect]). Ui :> es => Text -> Eff es () Source #
Dimmed menu row that cannot be clicked.
menuSeparator :: forall (es :: [Effect]). Ui :> es => Eff es () Source #
Separator line inside a context menu, matching the text-field context
menu painter exactly: a 1px rule inset menuItemPadX from the panel edge
(the popup already contributes menuOuterPad, the row adds the remainder)
centered in a menuSepH band (lineY = bandY + h/2 via 4.5px vertical
padding around a zero-height content box). The rule sits in a tight
column so it stays horizontal (separator adapts to its parent's
direction and would grow vertically inside the padded row) and so the
default 3px container padding does not inset or stretch it.
menuHeader :: forall (es :: [Effect]). Ui :> es => Text -> Eff es () Source #
Header / category title inside a context menu.
contextMenu :: forall (es :: [Effect]) r a. (Ui :> es, HasResponse r) => r -> Eff es a -> Eff es (Maybe a) Source #
A context menu for any widget response, opened by right-clicking it. Returns the menu body's result while the menu is open.
contextMenuArea :: forall (es :: [Effect]) a b. Ui :> es => (Layout -> Layout) -> Eff es a -> (V2 -> Eff es b) -> Eff es (a, Maybe b) Source #
A container whose right-click opens a context menu. The menu body receives the position it was opened at.
useContextMenu :: forall (es :: [Effect]). Ui :> es => Eff es (Bool, V2, V2 -> Eff es (), Eff es ()) Source #
Open state for a context menu you position yourself: whether it is open, where it was opened, an action to open it at a point, and one to close it.
Inputs
checkbox :: forall (es :: [Effect]). Ui :> es => Text -> Bool -> Eff es Bool Source #
Checkbox with a caption. Pass whether it is checked; the result is the state after this frame's click or Space/Enter.
toggleSwitch :: forall (es :: [Effect]). Ui :> es => Bool -> Eff es Bool Source #
On/off switch. Pass the current state; the result is the state after this frame's click or Space/Enter.
toggleSwitchWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Bool -> Eff es Bool Source #
toggleSwitch with a layout modifier.
toggleSwitchWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Bool -> Eff es (Response, Bool) Source #
radio :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es Int Source #
A column of radio buttons over options in fold order. Pass the selected
index; the result is the index after this frame's click or arrow keys.
radio' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es (Response, Int) Source #
boundedRadio :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es a Source #
Radio buttons for every value of a bounded enum, labelled by encode.
boundedRadio' :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es (Response, a) Source #
enumRadio :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es a Source #
boundedRadio labelled with show.
enumRadio' :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es (Response, a) Source #
select :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es Int Source #
Dropdown over options in fold order. Pass the selected index; the result
is the index after this frame's pick.
select' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => f Text -> Int -> Eff es (Response, Int) Source #
selectWith :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => (Layout -> Layout) -> f Text -> Int -> Eff es Int Source #
select with a layout modifier.
selectWith' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => (Layout -> Layout) -> f Text -> Int -> Eff es (Response, Int) Source #
boundedSelect :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es a Source #
Select over every value of a bounded enum, labelled by encode.
boundedSelect' :: forall a (es :: [Effect]). (Bounded a, Enum a, Ui :> es) => (a -> Text) -> a -> Eff es (Response, a) Source #
enumSelect :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es a Source #
boundedSelect labelled with show.
enumSelect' :: forall a (es :: [Effect]). (Bounded a, Enum a, Show a, Ui :> es) => a -> Eff es (Response, a) Source #
slider :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es Float Source #
Slider over [minV, maxV] that fills the available width. Pass the
current value; the result is the value after this frame's drag or arrow
keys.
slider' :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es (Response, Float) Source #
sliderWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Eff es Float Source #
slider with a layout modifier.
volume' <- sliderWith (fixedW 200) 0 100 volume
sliderWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Eff es (Response, Float) Source #
knob :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es Float Source #
Rotary knob over [minV, maxV], 36 px across. Drag vertically, scroll,
or use the arrow keys. Pass the current value; the result is the value
after this frame.
knob' :: forall (es :: [Effect]). Ui :> es => Float -> Float -> Float -> Eff es (Response, Float) Source #
knobWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Float -> Eff es Float Source #
knob with a layout modifier and a diameter in pixels.
knobWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Float -> Float -> Eff es (Response, Float) Source #
data TextInputConfig Source #
Constructors
| TextInputConfig | |
Fields
| |
Instances
| Eq TextInputConfig Source # | |
Defined in NanoUI.Widgets.TextInput Methods (==) :: TextInputConfig -> TextInputConfig -> Bool # (/=) :: TextInputConfig -> TextInputConfig -> Bool # | |
| Show TextInputConfig Source # | |
Defined in NanoUI.Widgets.TextInput Methods showsPrec :: Int -> TextInputConfig -> ShowS # show :: TextInputConfig -> String # showList :: [TextInputConfig] -> ShowS # | |
textInput :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Text Source #
Single-line text field. Pass the current text; the result is the text after this frame's typing, pastes, and menu edits.
textInputConfigured :: forall (es :: [Effect]). Ui :> es => TextInputConfig -> Text -> Eff es Text Source #
textInput with a placeholder, password masking, or its own layout.
secret' <- textInputConfigured defaultTextInputConfig {ticPassword = True} secret
textInputConfigured' :: forall (es :: [Effect]). Ui :> es => TextInputConfig -> Text -> Eff es (Response, Text) Source #
data NumericInputConfig Source #
How a numeric field reads, shows, and steps its value.
Constructors
| NumericInputConfig | |
Fields
| |
Instances
| Eq NumericInputConfig Source # | |
Defined in NanoUI.Widgets.NumericInput Methods (==) :: NumericInputConfig -> NumericInputConfig -> Bool # (/=) :: NumericInputConfig -> NumericInputConfig -> Bool # | |
| Show NumericInputConfig Source # | |
Defined in NanoUI.Widgets.NumericInput Methods showsPrec :: Int -> NumericInputConfig -> ShowS # show :: NumericInputConfig -> String # showList :: [NumericInputConfig] -> ShowS # | |
numericInput :: forall (es :: [Effect]). Ui :> es => Double -> Eff es Double Source #
Numeric field over whole numbers. Pass the current value; the result is the value after this frame's typing, arrow keys, and stepper clicks.
Only digits, and a leading minus sign when the range reaches below zero, can be typed. Up and Down step the value, Shift steps ten times as far, and holding a stepper arrow repeats. Enter, a step, or leaving the field rewrites the text as the value, clamped to the range.
numericInputConfigured :: forall (es :: [Effect]). Ui :> es => NumericInputConfig -> Double -> Eff es Double Source #
numericInput with a range, a step, decimal places, hexadecimal mode, or
its own layout.
byte' <- numericInputConfigured defaultNumericInputConfig {nicMin = 0, nicMax = 255, nicHex = True} byte
numericInputConfigured' :: forall (es :: [Effect]). Ui :> es => NumericInputConfig -> Double -> Eff es (Response, Double) Source #
data SearchFieldConfig Source #
Search field: a caption-less NodeTextInput with an embedded magnifier and
clear button. The label acts as the placeholder. Change pulses are debounced
(trailing edge); clearing with the embedded button fires immediately.
Constructors
| SearchFieldConfig | |
Fields
| |
Instances
| Eq SearchFieldConfig Source # | |
Defined in NanoUI.Widgets.TextInput Methods (==) :: SearchFieldConfig -> SearchFieldConfig -> Bool # (/=) :: SearchFieldConfig -> SearchFieldConfig -> Bool # | |
| Show SearchFieldConfig Source # | |
Defined in NanoUI.Widgets.TextInput Methods showsPrec :: Int -> SearchFieldConfig -> ShowS # show :: SearchFieldConfig -> String # showList :: [SearchFieldConfig] -> ShowS # | |
searchField :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es Text Source #
Search box with a magnifier and a clear button; the first argument is the
placeholder. Pass the current text; the result is the text after this
frame. respChanged on searchField' is debounced: it fires once typing
pauses, or at once when the field is cleared.
searchField' :: forall (es :: [Effect]). Ui :> es => Text -> Text -> Eff es (Response, Text) Source #
searchFieldConfigured :: forall (es :: [Effect]). Ui :> es => SearchFieldConfig -> Text -> Eff es Text Source #
searchFieldConfigured' :: forall (es :: [Effect]). Ui :> es => SearchFieldConfig -> Text -> Eff es (Response, Text) Source #
comboBox :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f Text -> Text -> Eff es Text Source #
Combo box: the searchField with a select-style dropdown of options.
While the field holds focus, the shared select dropdown overlay lists the
options filtered by the field text (all of them while it is empty). The
value is free text: options are suggestions, not a closed set. See
comboStep for when the value commits. Pass the current text; the result is
the text after this frame, and respChanged on comboBox' marks a commit.
comboBox' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f Text -> Text -> Eff es (Response, Text) Source #
textArea :: forall (es :: [Effect]). Ui :> es => Text -> Eff es Text Source #
Multi-line text editor. Pass the current text; the result is the text
after this frame's edits. Pair it with a label when a caption is wanted.
textAreaWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es Text Source #
textArea with a modifier applied to textAreaLayout, for example
grow to fill the parent.
textAreaWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Text -> Eff es (Response, Text) Source #
colorPicker :: forall (es :: [Effect]). Ui :> es => Color -> Eff es Color Source #
RGB colour picker: a saturation/value field, a hue bar, and RGB, HSV and hex fields. Pass the current colour; the result is the colour after this frame's edits.
The field and each bar take keyboard focus in turn. On the field the arrow keys move the marker (left and right for saturation, up and down for value); on a bar they move its handle, and Home and End jump to its ends. Shift takes steps ten times larger.
colorPickerRGBA :: forall (es :: [Effect]). Ui :> es => Color -> Eff es Color Source #
colorPicker with an alpha bar and an A / #RRGGBBAA field.
colorToHex :: Color -> Text Source #
colorToHexA :: Color -> Text Source #
Eight-digit form for the alpha-aware picker: #RRGGBBAA.
Text editing
Text fields change their text only through TextCommands. Keys run
them (Backspace is , Ctrl+Z is Delete CharLeftUndo), the
right-click menu runs them, and an app can run them on a field by its
id:
(resp, body') <-textArea'body canUndo <-textCanUndo(respIdresp)whenM(menuItem"Undo") (runTextCommand(respIdresp)Undo)whenM(menuItem"Insert date") (runTextCommand(respIdresp) (InsertTexttoday))
Every command that changes text is recorded for undo. Typing joins one undo step per word and deleting one per run; the steps keep the edits themselves, not copies of the document, so a long history of a large document stays small. Replacing the value a field is passed clears its history.
data TextCommand Source #
Something done to a text field. Commands that change text are undoable and replace the selection where one exists.
Constructors
| InsertText !Text | Replace the selection with text (typing, a snippet). |
| Delete !TextMotion | Delete the selection, or from the cursor to where the motion lands:
|
| Move !TextMotion !Bool | Move the cursor, extending the selection when the flag is set. |
| SelectAll | |
| Select !Cursor !Cursor | Select from the first position (the anchor) to the second (the cursor), clamped into the document. |
| Replace !Cursor !Cursor !Text | Replace the text between two positions, leaving the cursor after it. |
| ReplaceAll !Text | Replace the whole document as one undoable edit. |
| Undo | |
| Redo | |
| Cut | |
| Copy | |
| Paste |
Instances
| Eq TextCommand Source # | |
Defined in NanoUI.Widgets.TextCommand | |
| Show TextCommand Source # | |
Defined in NanoUI.Widgets.TextCommand Methods showsPrec :: Int -> TextCommand -> ShowS # show :: TextCommand -> String # showList :: [TextCommand] -> ShowS # | |
data TextMotion Source #
Where a motion takes the cursor.
Constructors
| CharLeft | |
| CharRight | |
| WordLeft | |
| WordRight | |
| LineStart | |
| LineEnd | |
| LineUp | |
| LineDown | |
| DocumentStart | |
| DocumentEnd |
Instances
| Eq TextMotion Source # | |
Defined in NanoUI.Widgets.TextCommand | |
| Bounded TextMotion Source # | |
Defined in NanoUI.Widgets.TextCommand | |
| Enum TextMotion Source # | |
Defined in NanoUI.Widgets.TextCommand Methods succ :: TextMotion -> TextMotion # pred :: TextMotion -> TextMotion # toEnum :: Int -> TextMotion # fromEnum :: TextMotion -> Int # enumFrom :: TextMotion -> [TextMotion] # enumFromThen :: TextMotion -> TextMotion -> [TextMotion] # enumFromTo :: TextMotion -> TextMotion -> [TextMotion] # enumFromThenTo :: TextMotion -> TextMotion -> TextMotion -> [TextMotion] # | |
| Show TextMotion Source # | |
Defined in NanoUI.Widgets.TextCommand Methods showsPrec :: Int -> TextMotion -> ShowS # show :: TextMotion -> String # showList :: [TextMotion] -> ShowS # | |
Zero-indexed logical (row, column) position in the buffer. Fields are
row then column, so the derived Ord is document order.
runTextCommand :: forall (es :: [Effect]). Ui :> es => WidgetId -> TextCommand -> Eff es () Source #
Run a command on the text field (text input, search field, text area)
with this id, as if its keys were pressed: runTextCommand (respId resp)
Undo. The field takes keyboard focus, and its next frame returns the
changed text and a respChanged pulse. An id that is not a text
field is ignored.
textCanUndo :: forall (es :: [Effect]). Ui :> es => WidgetId -> Eff es Bool Source #
Whether Undo would change the field, for
enabling a menu item.
textCanRedo :: forall (es :: [Effect]). Ui :> es => WidgetId -> Eff es Bool Source #
Whether Redo would change the field, for
enabling a menu item.
Tabs, trees, and tables
Constructors
| TabUnderline | |
| TabPill | |
| TabSegmented | |
| TabContained |
Instances
| Eq TabStyle Source # | |
| Bounded TabStyle Source # | |
| Enum TabStyle Source # | |
Defined in NanoUI.Widgets.Tabs | |
| Show TabStyle Source # | |
data TabOrientation Source #
Instances
| Eq TabOrientation Source # | |
Defined in NanoUI.Widgets.Tabs Methods (==) :: TabOrientation -> TabOrientation -> Bool # (/=) :: TabOrientation -> TabOrientation -> Bool # | |
| Bounded TabOrientation Source # | |
Defined in NanoUI.Widgets.Tabs | |
| Enum TabOrientation Source # | |
Defined in NanoUI.Widgets.Tabs Methods succ :: TabOrientation -> TabOrientation # pred :: TabOrientation -> TabOrientation # toEnum :: Int -> TabOrientation # fromEnum :: TabOrientation -> Int # enumFrom :: TabOrientation -> [TabOrientation] # enumFromThen :: TabOrientation -> TabOrientation -> [TabOrientation] # enumFromTo :: TabOrientation -> TabOrientation -> [TabOrientation] # enumFromThenTo :: TabOrientation -> TabOrientation -> TabOrientation -> [TabOrientation] # | |
| Show TabOrientation Source # | |
Defined in NanoUI.Widgets.Tabs Methods showsPrec :: Int -> TabOrientation -> ShowS # show :: TabOrientation -> String # showList :: [TabOrientation] -> ShowS # | |
data TabResponse a Source #
Constructors
| TabResponse | |
Fields
| |
Instances
| Eq a => Eq (TabResponse a) Source # | |
Defined in NanoUI.Widgets.Tabs Methods (==) :: TabResponse a -> TabResponse a -> Bool # (/=) :: TabResponse a -> TabResponse a -> Bool # | |
| Show a => Show (TabResponse a) Source # | |
Defined in NanoUI.Widgets.Tabs Methods showsPrec :: Int -> TabResponse a -> ShowS # show :: TabResponse a -> String # showList :: [TabResponse a] -> ShowS # | |
| HasResponse (TabResponse a) Source # | |
Defined in NanoUI.Widgets.Tabs Methods toResponse :: TabResponse a -> Response Source # | |
data TabsConfig Source #
Header look and placement for tabsConfigured and tabBarConfigured.
Constructors
| TabsConfig | |
Fields | |
Instances
| Eq TabsConfig Source # | |
Defined in NanoUI.Widgets.Tabs | |
| Show TabsConfig Source # | |
Defined in NanoUI.Widgets.Tabs Methods showsPrec :: Int -> TabsConfig -> ShowS # show :: TabsConfig -> String # showList :: [TabsConfig] -> ShowS # | |
defaultTabsConfig :: TabsConfig Source #
Underlined headers along the top.
closableTab :: a -> Text -> body -> Tab a body Source #
tabs :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => a -> f (Tab a (Eff es ())) -> Eff es a Source #
Tab headers and the active tab's body. Pass the active key; the result is the active key after this frame's clicks or arrow keys. Only the active tab's body runs.
tabs' :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => a -> f (Tab a (Eff es ())) -> Eff es (TabResponse a) Source #
tabs returning the TabResponse, which also reports a closed tab.
tabsConfigured :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a (Eff es ())) -> Eff es a Source #
tabs with a header style and placement.
tabsConfigured' :: forall f a (es :: [Effect]). (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a (Eff es ())) -> Eff es (TabResponse a) Source #
tabBar :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => a -> f (Tab a body) -> Eff es a Source #
Tab headers only; the caller renders the body.
tabBar' :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => a -> f (Tab a body) -> Eff es (TabResponse a) Source #
tabBarConfigured :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a body) -> Eff es a Source #
tabBarConfigured' :: forall f a (es :: [Effect]) body. (Foldable f, Eq a, Ui :> es) => TabsConfig -> a -> f (Tab a body) -> Eff es (TabResponse a) Source #
Constructors
| TreeItem | |
Fields
| |
Instances
tree :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f TreeItem -> Int -> Eff es Int Source #
Collapsible tree. Rows are numbered in pre-order; pass the selected row
and the result is the selection after this frame's click or arrow keys.
Expansion is kept by the widget. key distinguishes trees in one scope.
tree' :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => Text -> f TreeItem -> Int -> Eff es (Response, Int) Source #
Instances
| Eq SortDir Source # | |
| Bounded SortDir Source # | |
| Enum SortDir Source # | |
| Show SortDir Source # | |
Constructors
| SortCol | |
Fields
| |
Instances
Constructors
| ColContent | |
| ColStretch | |
| ColFixed Float |
Instances
data TableConfig Source #
Constructors
| TableConfig | |
Fields
| |
Instances
| Eq TableConfig Source # | |
Defined in NanoUI.Widgets.Table | |
| Show TableConfig Source # | |
Defined in NanoUI.Widgets.Table Methods showsPrec :: Int -> TableConfig -> ShowS # show :: TableConfig -> String # showList :: [TableConfig] -> ShowS # | |
data TableResponse Source #
Constructors
| TableResponse | |
Fields
| |
Instances
| Eq TableResponse Source # | |
Defined in NanoUI.Widgets.Table Methods (==) :: TableResponse -> TableResponse -> Bool # (/=) :: TableResponse -> TableResponse -> Bool # | |
| Show TableResponse Source # | |
Defined in NanoUI.Widgets.Table Methods showsPrec :: Int -> TableResponse -> ShowS # show :: TableResponse -> String # showList :: [TableResponse] -> ShowS # | |
| HasResponse TableResponse Source # | |
Defined in NanoUI.Widgets.Table Methods toResponse :: TableResponse -> Response Source # | |
table :: forall f (es :: [Effect]) row. (Foldable f, Ui :> es) => Text -> Colonnade Headed row Text -> f row -> SortCol -> Eff es TableResponse Source #
Sortable table with resizable, reorderable columns. key tells tables in
one scope apart, and the columns are a colonnade over row. Pass the
current sort; the TableResponse carries the sort after this frame's
header clicks, along with the column order and hidden columns.
tableWith :: forall f (es :: [Effect]) row. (Foldable f, Ui :> es) => (Layout -> Layout) -> Text -> Colonnade Headed row Text -> f row -> SortCol -> Eff es TableResponse Source #
table with a layout modifier.
tableConfigured :: forall f (es :: [Effect]) row. (Foldable f, Ui :> es) => TableConfig -> (Layout -> Layout) -> Text -> Colonnade Headed row Text -> f row -> SortCol -> Eff es TableResponse Source #
tableWith with column sizes, frozen rows and columns, and initially
hidden columns.
simpleTable :: forall f (es :: [Effect]). (Foldable f, Ui :> es) => [Text] -> f [Text] -> Eff es TableResponse Source #
A table of text rows under the given headers.
useTableSort :: forall (es :: [Effect]). Ui :> es => SortCol -> Eff es (SortCol, SortCol -> Eff es ()) Source #
tableHiddenIndices :: TableResponse -> [Int] Source #
data Colonnade (h :: Type -> Type) a c #
An columnar encoding of a. The type variable h determines what
is present in each column in the header row. It is typically instantiated
to Headed and occasionally to Headless. There is nothing that
restricts it to these two types, although they satisfy the majority
of use cases. The type variable c is the content type. This can
be Text, String, or ByteString. In the companion libraries
reflex-dom-colonnade and yesod-colonnade, additional types
that represent HTML with element attributes are provided that serve
as the content type. Presented more visually:
+---- Value consumed to build a row
|
v
Colonnade h a c
^ ^
| |
| +-- Content (Text, ByteString, Html, etc.)
|
+------ Headedness (Headed or Headless)Internally, a Colonnade is represented as a Vector of individual
column encodings. It is possible to use any collection type with
Alternative and Foldable instances. However, Vector was chosen to
optimize the data structure for the use case of building the structure
once and then folding over it many times. It is recommended that
Colonnades are defined at the top-level so that GHC avoids reconstructing
them every time they are used.
Instances
| Functor h => Profunctor (Colonnade h) # | |
Defined in Colonnade.Encode Methods dimap :: (a -> b) -> (c -> d) -> Colonnade h b c -> Colonnade h a d # lmap :: (a -> b) -> Colonnade h b c -> Colonnade h a c # rmap :: (b -> c) -> Colonnade h a b -> Colonnade h a c # (#.) :: forall a b c q. Coercible c b => q b c -> Colonnade h a b -> Colonnade h a c # (.#) :: forall a b c q. Coercible b a => Colonnade h b c -> q a b -> Colonnade h a c # | |
| Functor h => Functor (Colonnade h a) # | |
| Monoid (Colonnade h a c) # | |
| Semigroup (Colonnade h a c) # | |
As the first argument to the Colonnade type
constructor, this indictates that the columnar encoding has
a header. This type is isomorphic to Identity but is
given a new name to clarify its intent:
example :: Colonnade Headed Foo Text
The term example represents a columnar encoding of Foo
in which the columns have headings.
Instances
| Headedness Headed # | |
Defined in Colonnade.Encode | |
| Applicative Headed # | |
| Functor Headed # | |
| Foldable Headed # | |
Defined in Colonnade.Encode Methods fold :: Monoid m => Headed m -> m # foldMap :: Monoid m => (a -> m) -> Headed a -> m # foldMap' :: Monoid m => (a -> m) -> Headed a -> m # foldr :: (a -> b -> b) -> b -> Headed a -> b # foldr' :: (a -> b -> b) -> b -> Headed a -> b # foldl :: (b -> a -> b) -> b -> Headed a -> b # foldl' :: (b -> a -> b) -> b -> Headed a -> b # foldr1 :: (a -> a -> a) -> Headed a -> a # foldl1 :: (a -> a -> a) -> Headed a -> a # elem :: Eq a => a -> Headed a -> Bool # maximum :: Ord a => Headed a -> a # minimum :: Ord a => Headed a -> a # | |
| Eq a => Eq (Headed a) # | |
| Ord a => Ord (Headed a) # | |
Defined in Colonnade.Encode | |
| Read a => Read (Headed a) # | |
| Show a => Show (Headed a) # | |
Overlays
modal :: forall (es :: [Effect]) a. Ui :> es => Bool -> Text -> Eff es a -> Eff es (Response, Maybe a) Source #
window :: forall (es :: [Effect]) a. Ui :> es => Bool -> Text -> Eff es a -> Eff es (Response, Maybe a) Source #
data PopupAnchor Source #
Constructors
| AnchorPoint !V2 | |
| AnchorRect !Rect |
Instances
| Eq PopupAnchor Source # | |
Defined in NanoUI.Types | |
| Show PopupAnchor Source # | |
Defined in NanoUI.Types Methods showsPrec :: Int -> PopupAnchor -> ShowS # show :: PopupAnchor -> String # showList :: [PopupAnchor] -> ShowS # | |
data PopupPlacement Source #
Constructors
| PlacementBelow | |
| PlacementAbove | |
| PlacementRight | |
| PlacementLeft | |
| PlacementAtCursor | |
| PlacementAuto |
Instances
| Eq PopupPlacement Source # | |
Defined in NanoUI.Types Methods (==) :: PopupPlacement -> PopupPlacement -> Bool # (/=) :: PopupPlacement -> PopupPlacement -> Bool # | |
| Show PopupPlacement Source # | |
Defined in NanoUI.Types Methods showsPrec :: Int -> PopupPlacement -> ShowS # show :: PopupPlacement -> String # showList :: [PopupPlacement] -> ShowS # | |
data PopupConfig Source #
Constructors
| PopupConfig | |
Fields
| |
Instances
| Eq PopupConfig Source # | |
Defined in NanoUI.Widgets.Popup | |
| Show PopupConfig Source # | |
Defined in NanoUI.Widgets.Popup Methods showsPrec :: Int -> PopupConfig -> ShowS # show :: PopupConfig -> String # showList :: [PopupConfig] -> ShowS # | |
popup :: forall (es :: [Effect]) a. Ui :> es => Bool -> PopupConfig -> Eff es a -> Eff es (Response, Maybe a) Source #
A floating panel placed by the config, shown while open. Returns the
body's result while open. The Response reports a dismissal (Escape, or a
click outside when cfgDismissable) as a click.
popupWith :: forall (es :: [Effect]) a. Ui :> es => Bool -> PopupConfig -> (Layout -> Layout) -> Eff es a -> Eff es (Response, Maybe a) Source #
popup with a modifier applied to its tight default layout.
tooltip :: forall (es :: [Effect]) r. (Ui :> es, HasResponse r) => r -> Text -> Eff es () Source #
Text shown below a widget while the pointer is over it.
save <- button' Save tooltip save "Write the file to disk"
tooltipAt :: forall (es :: [Effect]) r. (Ui :> es, HasResponse r) => PopupPlacement -> r -> Text -> Eff es () Source #
tooltip with a placement.
tooltipWidget :: forall (es :: [Effect]) r a. (Ui :> es, HasResponse r) => r -> Eff es a -> Eff es (Maybe a) Source #
Attach a rich tooltip widget to any target response, displayed on hover.
withTooltip :: forall (es :: [Effect]) a b. Ui :> es => Eff es a -> Eff es b -> Eff es (a, Maybe b) Source #
Attach a rich tooltip widget to an inner UI computation.
Pane grids
data PaneGridConfig (es :: [Effect]) Source #
Configuration for a pane grid. pgViewPane can run arbitrary widget code,
so the config carries the caller's effect row.
Constructors
| PaneGridConfig | |
Fields
| |
defaultPaneGridConfig :: forall (es :: [Effect]). PaneGridConfig es Source #
data PaneGridCtx (es :: [Effect]) Source #
Actions handed to a pane so it can mutate the grid immediately.
Constructors
| PaneGridCtx | |
Fields
| |
What a pane renders to this frame. The pane's content (including any title
bar / header) is drawn entirely by the caller in pgViewPane; a header is
purely optional and nothing here depends on one existing.
Constructors
| PaneView | |
Fields
| |
data PaneGridResponse Source #
Outcome of one frame of the grid. The pane list, focus, and maximize
fields report the state after this pass: actions run by pane content
(pgcSplit, pgcClose, ...) and the keyboard handling below take effect
in these values and from the next frame's layout onward.
Constructors
| PaneGridResponse | |
Fields
| |
Instances
| Eq PaneGridResponse Source # | |
Defined in NanoUI.Widgets.PaneGrid Methods (==) :: PaneGridResponse -> PaneGridResponse -> Bool # (/=) :: PaneGridResponse -> PaneGridResponse -> Bool # | |
| Show PaneGridResponse Source # | |
Defined in NanoUI.Widgets.PaneGrid Methods showsPrec :: Int -> PaneGridResponse -> ShowS # show :: PaneGridResponse -> String # showList :: [PaneGridResponse] -> ShowS # | |
Divider orientation. AxisV draws a vertical divider (panes left/right),
AxisH draws a horizontal divider (panes stacked top/bottom).
Instances
| Eq GridAxis Source # | |
| Ord GridAxis Source # | |
Defined in NanoUI.Widgets.SplitPane | |
| Bounded GridAxis Source # | |
| Enum GridAxis Source # | |
Defined in NanoUI.Widgets.SplitPane | |
| Show GridAxis Source # | |
paneGrid :: forall (es :: [Effect]). Ui :> es => PaneGridConfig es -> Eff es PaneGridResponse Source #
Progress and sparklines
progressBar :: forall (es :: [Effect]). Ui :> es => Float -> Eff es () Source #
Horizontal progress bar for a fraction in [0, 1]. It fills the
available width at a fixed height.
progressBarWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es () Source #
progressBar with a layout modifier and a bar height in pixels.
progressBarWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es Response Source #
circularProgress :: forall (es :: [Effect]). Ui :> es => Float -> Eff es () Source #
Progress ring for a fraction in [0, 1], 32 px across.
circularProgressWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es () Source #
circularProgress with a layout modifier and a diameter in pixels.
circularProgressWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> Eff es Response Source #
spinner :: forall (es :: [Effect]). Ui :> es => Eff es () Source #
An indeterminate loading indicator: a short accent arc turning over a faint ring, 18 px across. It keeps the frame loop running while it is on screen and repaints only its own rect.
spinnerWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Eff es () Source #
spinner with a layout modifier and a diameter in pixels.
spinnerWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Eff es Response Source #
A piece of a paragraph: text in one style, and the hyperlink it follows when
it is one. A string literal is plain text.
Instances
| IsString Inline Source # | |
Defined in NanoUI.Widgets.RichText Methods fromString :: String -> Inline # | |
inlineText :: Text -> Inline Source #
Text in the paragraph's own style.
inlineWith :: (Layout -> Layout) -> Text -> Inline Source #
Text styled by font modifiers (fontBold, fontSize 20,
fontColor red . fontUnderline), applied over the paragraph's layout.
restyle :: (Layout -> Layout) -> Inline -> Inline Source #
Add font modifiers to a piece, a hyperlink included.
inlineCode :: Text -> Inline Source #
Monospaced text.
hyperlink :: Text -> Text -> Inline Source #
hyperlink target label: text in the theme's link colour, underlined while
hovered, whose click the paragraph reports as target.
richText :: forall (es :: [Effect]). Ui :> es => [Inline] -> Eff es (Maybe Text) Source #
A paragraph of pieces, wrapped at its width. Returns the target of the hyperlink clicked this frame.
richText' :: forall (es :: [Effect]). Ui :> es => [Inline] -> Eff es (Response, Maybe Text) Source #
richTextWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> [Inline] -> Eff es (Maybe Text) Source #
richText with a layout modifier, whose font choices are the default
for every piece.
richTextWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> [Inline] -> Eff es (Response, Maybe Text) Source #
sparkline :: forall (es :: [Effect]). Ui :> es => [Float] -> Eff es () Source #
A small line chart of the values, 80 by 24 px, scaled to their range.
sparklineWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> [Float] -> Eff es () Source #
sparkline with a layout modifier and a width and height in pixels.
sparklineWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Float -> Float -> [Float] -> Eff es Response Source #
Images and drawing
image :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> ImageId -> Eff es () Source #
An image registered with the host, sized by the layout modifier.
image' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> ImageId -> Eff es Response Source #
image with its Response, for example to keepAnimating an
image whose id changes over time.
freshImageId :: forall (es :: [Effect]). Ui :> es => Eff es ImageId Source #
An image id that no registered image uses and no earlier call returned. Take one for each image registered while the app runs.
registerImageRgba :: forall (es :: [Effect]). Ui :> es => ImageId -> Int -> Int -> ByteString -> Eff es Bool Source #
A parsed SVG document.
svgIcon :: forall (es :: [Effect]). Ui :> es => Float -> Svg -> Eff es () Source #
An SVG icon size logical pixels square, drawn in the text colour where
it is used: a one-colour document (every paint currentColor or
unspecified) takes the colour as a tint, and a multicoloured one paints
its currentColor with it.
svgIconWith :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Svg -> Eff es () Source #
An SVG document sized by the layout modifier: a fixed width and height,
or else the document's own size. A fontColor in the modifier
replaces the text colour.
svgIconWith' :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Svg -> Eff es Response Source #
The document is rasterized once per pixel size and colour, at the display's scale, and kept in the image atlas for as long as the app runs.
svgSize :: Svg -> (Float, Float) Source #
The document's own width and height, from its width and height or
else its viewBox.
box :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> Color -> Eff es () Source #
A solid rectangle sized by the layout modifier.
drawing :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> (Rect -> SmallArray DrawOp) -> Eff es Response Source #
Vector ops for a laid-out widget. Paint caches ops while width and height
stay the same, then translates when the widget moves. Unversioned: the cache
drops while the widget animates because the builder has no content key, and
a builder that draws something else at the same size neither rebuilds nor
repaints. Use drawingVersioned for output that changes, or
customWidget without a key to have every frame
rebuild and compare.
drawingVersioned :: forall (es :: [Effect]). Ui :> es => Int -> (Layout -> Layout) -> (Rect -> SmallArray DrawOp) -> Eff es Response Source #
Like drawing, but the tessellated op cache is keyed by an explicit
content version. Change the version whenever the builder output changes
(a model pointer, dirty counter, or content hash): that rebuilds the ops and
repaints the widget. Frames with the same version replay cached ops without
rebuilding, even while the widget animates. Version 0 means unversioned, as
in drawing.
drawingCached :: forall (es :: [Effect]). Ui :> es => Double -> Double -> Float -> Int -> (Layout -> Layout) -> IO Layout -> DrawingBuild -> Eff es Response Source #
Like drawingVersioned, but the layout itself comes from compute, which
only reruns when the envelope, line height, content key, or modifier result
change.
Constructors
| FillRect !Rect !Color | |
| FillRoundedRect !Rect !Float !Color | |
| FillTriangle !Float !Float !Float !Float !Float !Float !Color | |
| FillCircle !Float !Float !Float !Color | |
| Stroke !Float !Float !Float !Float !Float !Color | |
| StrokeRoundedRect !Rect !Float !Float !Color | |
| StrokeCircle !Float !Float !Float !Float !Color | |
| StrokeLineAA !Float !Float !Float !Float !Float !Color | |
| FillQuadGradient !Rect !Color !Color !Color !Color | |
| DrawImageRect !Rect !Int !Float !Float !Float !Float !Color | |
| DrawText !Float !Float !Float !Float !Text !Color | Pen at (x, y) is the alignment point. ax 0..1 is left..right. ay 0..1 is
bottom..top. ay < 0 means baseline (x is left, y is the baseline). Glyph size
is the host font ( |
| DrawTextStyled !Float !Float !TextFont !Text !Color | Text in a font of its own, its line box's top left corner at (x, y). |
The font a DrawTextStyled draws with: the same choices a label's
layout makes.
Constructors
| TextFont | |
Fields
| |
Instances
defaultTextFont :: TextFont Source #
The theme's regular font.
type DrawingBuild = Rect -> SmallArray DrawOp Source #
drawTextBox :: FontMetrics -> Float -> Float -> Float -> Float -> Text -> Rect Source #
Pixel box for a DrawText using host advances. diagrams text has no
envelope, so plot sizing uses this instead of fontSizeL.
shiftDrawOp :: Float -> Float -> DrawOp -> DrawOp Source #
Translate every vertex in a DrawOp. Paint reuses ops when only (x, y) moved.
Custom widgets
data CustomWidgetSpec a Source #
Complete specification for defining a custom widget.
Constructors
| CustomWidgetSpec | |
Fields
| |
defaultCustomWidgetSpec :: CustomWidgetSpec () Source #
Default configuration for a custom widget with standard hoverpressclick behavior.
customWidget :: forall (es :: [Effect]) a. Ui :> es => CustomWidgetSpec a -> Eff es (Response, a) Source #
Instantiates a custom widget from a CustomWidgetSpec.
Connects the widget into:
- The two-pass layout arena (respecting widgetMeasure or layout constraints).
- Off-heap vector drawing pipeline. Without a widgetContent key the draw
function runs once a frame and the widget repaints when its ops change, so
it may read anything; with one, an unchanged key skips both.
- Interactive hit-testing, focus management, and custom cursor resolution.
- Accurate damage region tracking with widgetDamageSlop.
customWidgetWithId :: forall (es :: [Effect]) a. Ui :> es => WidgetId -> CustomWidgetSpec a -> Eff es (Response, a) Source #
Instantiates a custom widget using an existing WidgetId.
contentKey :: [Float] -> Int Source #
A widgetContent key for a drawing whose output follows these numbers.
Pass every value the drawing reads; 0 means "no key", so a hash that lands
there becomes 1.
data CustomDrawContext Source #
Constructors
| CustomDrawContext | |
Fields
| |
type CustomMeasureFn = FontMetrics -> (Float, Float) -> (Float, Float) Source #
Custom node measurement: font metrics and available (width, height) to the node's desired (width, height).
type CustomDrawBuild = CustomDrawContext -> Rect -> SmallArray DrawOp Source #
Monadic canvas builder that collects DrawOp vector operations efficiently.
runCanvas :: CanvasM a -> SmallArray DrawOp Source #
Compile a CanvasM block into an immutable 'SmallArray DrawOp'.
canvas :: forall (es :: [Effect]). Ui :> es => (Layout -> Layout) -> (Rect -> CanvasM ()) -> Eff es Response Source #
Draw into a rectangle sized by the layout modifier. Use customWidget
when the drawing needs hover or press state.
drawRoundedRect :: Rect -> Float -> Color -> CanvasM () Source #
Fill a rounded rectangle with given corner radius.
drawCircle :: V2 -> Float -> Color -> CanvasM () Source #
Fill a solid circle at center with given radius.
drawStroke :: V2 -> V2 -> Float -> Color -> CanvasM () Source #
Stroke a straight segment between two points with thickness.
drawStrokeRoundedRect :: Rect -> Float -> Float -> Color -> CanvasM () Source #
Stroke a rounded rectangle border with given radius and stroke width.
drawStrokeCircle :: V2 -> Float -> Float -> Color -> CanvasM () Source #
Stroke a circular outline at center with given radius and stroke width.
drawStrokeAA :: V2 -> V2 -> Float -> Color -> CanvasM () Source #
Antialiased smooth stroke line between two points.
drawQuadGradient :: Rect -> Color -> Color -> Color -> Color -> CanvasM () Source #
Four-corner bilinear gradient fill (top-left, top-right, bottom-right, bottom-left).
drawLinearGradientH :: Rect -> Color -> Color -> CanvasM () Source #
Horizontal 2-color linear gradient fill (left to right).
drawLinearGradientV :: Rect -> Color -> Color -> CanvasM () Source #
Vertical 2-color linear gradient fill (top to bottom).
drawImage :: Rect -> ImageId -> Color -> CanvasM () Source #
Draw a textured image stretched over given rectangle.
drawImageUV :: Rect -> ImageId -> Float -> Float -> Float -> Float -> Color -> CanvasM () Source #
Draw a sub-region of a textured image with explicit UV texture coordinates.
drawText :: V2 -> AlignX -> AlignY -> Text -> Color -> CanvasM () Source #
Draw text positioned at a reference point with horizontal and vertical alignment.
useDrag2D :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es Drag2D Source #
Tracks pointer dragging across a 2D area (e.g. for color pickers, joysticks, canvas panning).
Result of a 2D drag gesture.
Constructors
| Drag2D | |
Fields
| |
useWheelDelta :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es (Float, Float) Source #
Inspects mouse wheel scroll delta when pointer is hovering over bounds.
Drag and drop
OS-level drag-and-drop event kind, mirroring SDL_EventType drop codes.
Constructors
| DropBegin | A drag enters the window; no position or payload yet. |
| DropPosition | The drag pointer moved over the window; position available. |
| DropFile | A file path was dropped; |
| DropText | Text was dropped; |
| DropComplete | The OS drag operation finished. |
A single normalized drop payload surfaced to widgets.
Constructors
| DropEvent | |
Fields
| |
Instances
data DropTarget Source #
Per-frame drop state for a single rectangular drop target.
Constructors
| DropTarget | |
Fields
| |
Instances
| Eq DropTarget Source # | |
Defined in NanoUI.Widgets.Drop | |
| Show DropTarget Source # | |
Defined in NanoUI.Widgets.Drop Methods showsPrec :: Int -> DropTarget -> ShowS # show :: DropTarget -> String # showList :: [DropTarget] -> ShowS # | |
useDrop :: forall (es :: [Effect]). Ui :> es => Rect -> Eff es DropTarget Source #
Compute the drop state for a rectangle from the current frame's drop events.
Active/hover state persists across frames in the widget store, so a target
keeps highlighting while the OS drag is stationary. Payload events
(DropFile/DropText) are one-shot: they are reported exactly on the frame
they arrive.
Attribution uses the tracked drag position (the coordinates of the most
recent DropPosition) rather than a payload's own coordinates. SDL
synthesizes file/text events at the last drag position and reports (0,0)
when it never observed one, so the position stream is the only reliable
signal for "which target is this drop over".
dropZone :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es (a, Response, DropTarget) Source #
A panel that is also a drop target. Returns the body's result, the
panel's Response, and the DropTarget for its rect.
Local state
useState :: forall a (es :: [Effect]). (Typeable a, Eq a, Ui :> es) => a -> Eff es (a, a -> Eff es ()) Source #
useFloat :: forall (es :: [Effect]). Ui :> es => Float -> Eff es (Float, Float -> Eff es ()) Source #
useEnum :: forall a (es :: [Effect]). (Enum a, Ui :> es) => a -> Eff es (a, a -> Eff es ()) Source #
Scrolling
A scroll container (scroll, scroll2D) handles the wheel and its
own scrollbars. These move one from the outside, keyed by the
WidgetId that scrollArea and scrollArea2D hand back.
How far the wheel goes, and whether a scroll glides onto its target instead of jumping, is one setting for the whole app:
setScrollTuningctxdefaultScrollTuning{scrollWheelStep= 3 * rowHeight -- three rows a notch ,scrollSmoothTime= 0.12 -- glide onto it }
setScrollStep gives one list a step of its own. With a glide time
set, every wheel notch and every ScrollSmooth command eases onto its
target over that many seconds, and the frame loop keeps drawing until
it lands.
scrollIntoView brings a widget inside the scroller into view: the row
a keyboard selection just moved to, say. A list that only builds the
rows it shows has no widget to point at for the rest, so scroll to
where the row would be with scrollRectIntoView, whose rectangle is in
content coordinates. getScrollMetrics reports the viewport, range and
offset such a list needs to pick its visible rows in the first place.
data ScrollTuning Source #
How far one wheel notch scrolls, and how long a scroll takes to settle.
One setting for the whole context; a single scroller can take its own step
(see setScrollStep).
Constructors
| ScrollTuning | |
Fields
| |
Instances
| Eq ScrollTuning Source # | |
Defined in NanoUI.Context.Types | |
| Show ScrollTuning Source # | |
Defined in NanoUI.Context.Types Methods showsPrec :: Int -> ScrollTuning -> ShowS # show :: ScrollTuning -> String # showList :: [ScrollTuning] -> ShowS # | |
getScrollTuning :: Context -> IO ScrollTuning Source #
Wheel step and glide time for every scroller in this context.
setScrollTuning :: Context -> ScrollTuning -> IO () Source #
Set the wheel step and glide time. Raising scrollWheelStep makes the
wheel cover more ground per notch; a nonzero scrollSmoothTime turns every
wheel notch and every ScrollSmooth command into a glide.
getScrollStep :: Context -> WidgetId -> IO Float Source #
This scroller's own wheel step, or 0 when it follows the context's.
setScrollStep :: Context -> WidgetId -> Float -> IO () Source #
Give one scroller its own wheel step, in pixels per notch. 0 puts it
back on the context's step. A list whose rows are a fixed height reads best
at a whole number of rows per notch.
data ScrollMetrics Source #
What a scroller looked like on the frame it was last laid out on.
Offsets and ranges are in window axes: x rightwards, y downwards,
whichever way the scroller itself is built.
Constructors
| ScrollMetrics | |
Fields
| |
Instances
| Eq ScrollMetrics Source # | |
Defined in NanoUI.Context.Scroll Methods (==) :: ScrollMetrics -> ScrollMetrics -> Bool # (/=) :: ScrollMetrics -> ScrollMetrics -> Bool # | |
| Show ScrollMetrics Source # | |
Defined in NanoUI.Context.Scroll Methods showsPrec :: Int -> ScrollMetrics -> ShowS # show :: ScrollMetrics -> String # showList :: [ScrollMetrics] -> ShowS # | |
data ScrollAxes Source #
Which axes a scroller moves on, and how an offset in window axes (x rightwards, y downwards) maps onto its stored offset. A 1D row scroller keeps its offset in the main-axis slot, so its horizontal offset is the one that needs swapping.
Constructors
| ScrollAxisY | |
| ScrollAxisX | |
| ScrollAxisXY |
Instances
| Eq ScrollAxes Source # | |
Defined in NanoUI.Context.Types | |
| Show ScrollAxes Source # | |
Defined in NanoUI.Context.Types Methods showsPrec :: Int -> ScrollAxes -> ShowS # show :: ScrollAxes -> String # showList :: [ScrollAxes] -> ShowS # | |
getScrollMetrics :: Context -> WidgetId -> IO (Maybe ScrollMetrics) Source #
Geometry of the scroller wid, or Nothing before it has been laid out.
Reads the last frame's layout, so it is safe to call while building the
next one.
data ScrollBehavior Source #
Whether a scroll lands on its target at once or glides onto it.
ScrollSmooth still lands at once when the context's scrollSmoothTime is
0, so one setting turns smooth scrolling on for the whole app.
Constructors
| ScrollInstant | |
| ScrollSmooth |
Instances
| Eq ScrollBehavior Source # | |
Defined in NanoUI.Context.Scroll Methods (==) :: ScrollBehavior -> ScrollBehavior -> Bool # (/=) :: ScrollBehavior -> ScrollBehavior -> Bool # | |
| Show ScrollBehavior Source # | |
Defined in NanoUI.Context.Scroll Methods showsPrec :: Int -> ScrollBehavior -> ShowS # show :: ScrollBehavior -> String # showList :: [ScrollBehavior] -> ShowS # | |
data ScrollAlign Source #
Where a widget ends up in the viewport once it is scrolled into view.
Constructors
| ScrollNearest | Move as little as possible: nothing at all when it is already whole. |
| ScrollStart | Against the leading edge, at the top or left. |
| ScrollCenter | |
| ScrollEnd | Against the trailing edge, at the bottom or right. |
Instances
| Eq ScrollAlign Source # | |
Defined in NanoUI.Context.Scroll | |
| Show ScrollAlign Source # | |
Defined in NanoUI.Context.Scroll Methods showsPrec :: Int -> ScrollAlign -> ShowS # show :: ScrollAlign -> String # showList :: [ScrollAlign] -> ShowS # | |
scrollTo :: Context -> WidgetId -> V2 -> ScrollBehavior -> IO () Source #
Scroll to an absolute offset, clamped to the scroller's range.
scrollBy :: Context -> WidgetId -> V2 -> ScrollBehavior -> IO () Source #
Scroll by a delta in pixels. Deltas accumulate onto a glide already in flight, so repeated calls keep up rather than fighting each other.
scrollPages :: Context -> WidgetId -> V2 -> ScrollBehavior -> IO () Source #
Scroll by whole viewports: V2 0 1 is one page down, V2 0 (-0.5) half
a page up.
scrollToStart :: Context -> WidgetId -> ScrollBehavior -> IO () Source #
Scroll back to the top (and left).
scrollToEnd :: Context -> WidgetId -> ScrollBehavior -> IO () Source #
Scroll to the end of the content.
scrollIntoView :: Context -> WidgetId -> WidgetId -> ScrollAlign -> ScrollBehavior -> IO () Source #
Scroll target into the viewport of the scroller wid it is built
inside. Both widgets are read from the last frame's layout, so a widget
that was not built then, such as a row a virtualized list left out, cannot
be found; scroll to its content rectangle with scrollRectIntoView instead.
scrollRectIntoView :: Context -> WidgetId -> Rect -> ScrollAlign -> ScrollBehavior -> IO () Source #
Scroll a rectangle of the content into view. The rectangle is in content
coordinates: the origin is where the content starts, which is where the
viewport shows it at offset 0.
setScrollOffset :: Context -> WidgetId -> Float -> IO () Source #
Move a scroller to an offset along its main axis. Cancels a glide in flight: whoever sets an offset outright owns it.
setScrollOffset2D :: Context -> WidgetId -> V2 -> IO () Source #
Move a scroller to an offset on both axes. Cancels a glide in flight.
Animation
data Transition Source #
How an animated value moves.
animate :: forall (es :: [Effect]). Ui :> es => Transition -> Float -> Float -> Eff es Float Source #
Animate from from to to. It starts over from from once it has
finished (a tween completes, a spring settles) or its tween changes, so
calling it every frame cycles.
animateTo :: forall (es :: [Effect]). Ui :> es => Transition -> Float -> Eff es Float Source #
Animate from the current value toward target. An unchanged target keeps
the running animation; a new one retargets from wherever the value is.
animateToA :: forall a (es :: [Effect]). (Animatable a, Ui :> es) => Transition -> a -> Eff es a Source #
animateTo for every component of a composite value.
pulse :: forall (es :: [Effect]). Ui :> es => Float -> Eff es Float Source #
A smoothly oscillating value in [0,1] driven by the real-time clock, with
the given period in seconds (e.g. pulse 6 sweeps once every six seconds).
The time is captured in Double (see uiTime), so the sweep
stays sub-frame smooth even on long-running processes. The value is
re-evaluated each frame, like animate.
keepAnimating :: forall r (es :: [Effect]). (HasResponse r, Ui :> es) => r -> Eff es () Source #
class Animatable a where Source #
Instances
| Animatable Color Source # | |
Defined in NanoUI.Animatable | |
| Animatable V2 Source # | |
Defined in NanoUI.Animatable | |
| Animatable Double Source # | |
Defined in NanoUI.Animatable | |
| Animatable Float Source # | |
Defined in NanoUI.Animatable | |
data SpringParams Source #
Constructors
| SpringParams | |
Fields
| |
Instances
| Eq SpringParams Source # | |
Defined in NanoUI.Animation | |
| Show SpringParams Source # | |
Defined in NanoUI.Animation Methods showsPrec :: Int -> SpringParams -> ShowS # show :: SpringParams -> String # showList :: [SpringParams] -> ShowS # | |
Layout
Constructors
| Layout | |
Fields
| |
type LayoutModifier = Layout -> Layout Source #
Instances
| Eq Direction Source # | |
| Bounded Direction Source # | |
| Enum Direction Source # | |
Defined in NanoUI.Style Methods succ :: Direction -> Direction # pred :: Direction -> Direction # fromEnum :: Direction -> Int # enumFrom :: Direction -> [Direction] # enumFromThen :: Direction -> Direction -> [Direction] # enumFromTo :: Direction -> Direction -> [Direction] # enumFromThenTo :: Direction -> Direction -> Direction -> [Direction] # | |
| Show Direction Source # | |
Constructors
| AlignStart | |
| AlignCenter | |
| AlignEnd |
AlignBaseline lines a row's text children up on their first baseline, and
sits any other child on it by its bottom edge. Outside a row it is
AlignTop.
Constructors
| AlignTop | |
| AlignMiddle | |
| AlignBottom | |
| AlignBaseline |
withDefaultLayout :: forall (es :: [Effect]) a. Ui :> es => (Layout -> Layout) -> Eff es a -> Eff es a Source #
alignStart :: Layout -> Layout Source #
alignCenter :: Layout -> Layout Source #
alignBottom :: Layout -> Layout Source #
alignBaseline :: Layout -> Layout Source #
Sit on the row's shared text baseline, so labels of different sizes read
as one line of type. alignBottom lines up their boxes instead, and a larger
font's deeper descent lifts its baseline above the smaller one's.
Text style
data FontVariant Source #
Constructors
| FontRegular | |
| FontHeading | |
| FontMuted | |
| FontMono | |
| FontDanger |
Instances
data FontWeight Source #
Constructors
| WeightNormal | |
| WeightBold | |
| WeightLight | |
| WeightMedium | |
| WeightSemiBold | |
| WeightExtraBold | |
| WeightBlack |
Instances
Constructors
| FontStyleNormal | |
| FontStyleItalic | |
| FontStyleOblique |
Instances
| Eq FontStyle Source # | |
| Ord FontStyle Source # | |
| Bounded FontStyle Source # | |
| Enum FontStyle Source # | |
Defined in NanoUI.Style Methods succ :: FontStyle -> FontStyle # pred :: FontStyle -> FontStyle # fromEnum :: FontStyle -> Int # enumFrom :: FontStyle -> [FontStyle] # enumFromThen :: FontStyle -> FontStyle -> [FontStyle] # enumFromTo :: FontStyle -> FontStyle -> [FontStyle] # enumFromThenTo :: FontStyle -> FontStyle -> FontStyle -> [FontStyle] # | |
| Show FontStyle Source # | |
data TextDecoration Source #
Instances
fontRegular :: Layout -> Layout Source #
fontHeading :: Layout -> Layout Source #
fontDanger :: Layout -> Layout Source #
fontWeight :: FontWeight -> Layout -> Layout Source #
fontMedium :: Layout -> Layout Source #
fontSemiBold :: Layout -> Layout Source #
fontExtraBold :: Layout -> Layout Source #
fontItalic :: Layout -> Layout Source #
fontOblique :: Layout -> Layout Source #
textDecoration :: TextDecoration -> Layout -> Layout Source #
fontUnderline :: Layout -> Layout Source #
fontStrike :: Layout -> Layout Source #
Styling
A Theme says how every kind of widget looks: a Style for each
surface (buttons, inputs, panels, floating windows) and colours for
accents, text selection, links and so on. The context holds one theme
for the whole app (setTheme); styled changes it for part of the
view. Style and theme modifiers compose with (.) like layout
modifiers do:
toolbar =styled(subtle.buttonStyle(cornerRadius6)) $row$ dowhenM(button"Open") openFilestyledprimary(whenM(button"Save") save)
Scopes nest, and each one modifies the theme around it, so a modifier
written once (primary, destructive, or one of your own) works in any
theme. uiTheme reads the theme where it is called.
disabledWhen switches the widgets inside it off: they keep their
layout and state, take no input, and fade toward the window colour.
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
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.
Style modifiers
fillColor :: Color -> Style -> Style Source #
A background with hover and press shades derived from it: hovering mixes in some of the foreground, pressing darkens.
Theme modifiers
inputStyle :: (Style -> Style) -> Theme -> Theme Source #
Text fields, text areas, sliders' wells and scroller wells.
windowColor :: Color -> Theme -> Theme Source #
The backdrop behind everything, which disabled widgets also fade toward.
destructive :: Theme -> Theme Source #
Buttons in the theme's red, for destructive actions.
subtle :: Theme -> Theme Source #
Buttons without a fill or border until hovered, for toolbars and secondary actions.
tinted :: (Theme -> Color) -> Theme -> Theme Source #
Buttons filled with a colour picked from the theme, with a readable label.
styled (tinted themePurple) (button "Tag")
readableOn :: Theme -> Color -> Color Source #
Whichever of the theme's text colours reads best on c.
disabledTheme :: Theme -> Theme Source #
The theme disabled widgets are drawn with: every colour faded toward the
window colour by themeDisabledFade, and no hover or press feedback.
Themes
Constructors
| Theme | |
Fields
| |
Constructors
| Style | |
Fields
| |
defaultTheme :: Theme Source #
Neutral charcoal surfaces, warm text, and a blue selection accent. Keep structural edges quiet; interactive borders and focus carry contrast.
tomorrowNightMinDarkTheme :: Theme Source #
Ported from "Tomorrow Night Min" in https://github.com/biaqat/tomorrow-min-theme-zed
tomorrowMinLightTheme :: Theme Source #
Ported from "Tomorrow Min" in https://github.com/biaqat/tomorrow-min-theme-zed
tomorrowMidnightMinDarkTheme :: Theme Source #
Ported from "Tomorrow at Midnight Min" in https://github.com/biaqat/tomorrow-min-theme-zed
Standard Base16 palette containing 16 styling tones and syntax colours following Chris Kempson's Base16 specification.
Constructors
| Base16 | |
Fields
| |
themeFromBase16 :: Base16 -> Theme Source #
base16TomorrowNight :: Base16 Source #
Tomorrow Night Base16 reference palette.
base16TomorrowLight :: Base16 Source #
Tomorrow Light Base16 reference palette.
withTheme :: Context -> Theme -> IO Context Source #
Configure a context's theme. Goes through setTheme so a theme swapped
between frames invalidates the caches keyed on it, drawing-op caches
included, instead of leaving widgets painting the previous theme.
themeSeries :: Theme -> [Color] Source #
Geometry and colour
colorToWord32 :: Color -> Word32 Source #
colorLuminance :: Color -> Double Source #
contrastRatio :: Color -> Color -> Double Source #
WCAG 2 relative-luminance contrast. 4.5 is AA for normal text.
Alpha is ignored, so both colours must be opaque. Passing a translucent
colour such as themeOverlayDim gives a meaningless ratio;
composite it over its backdrop first.
onGrid :: Float -> Float -> Float Source #
Round a logical coordinate onto the device-pixel grid implied by draw
scale s (device px = logical * s). Every layer that positions pixels --
the layout solve, text pens, scroll offsets, paint and glyph rasterization --
must route its coordinates through this single function (backends through
roundHalfUp), so geometry can never dephase from text. An identity when
s <= 0 (no scaling).
roundHalfUp :: Float -> Int Source #
Round to the nearest integer, ties up: the device-pixel rounding shared by
onGrid and the backends. Not ties-to-even (round): at a fractional scale
(125%: a 20px row is 25 device px) a column of rows can all sit on half
pixels, and ties-to-even would alternate them down and up, leaving uneven
gaps. Compares the exact fractional part rather than floor (r + 0.5),
whose addition itself rounds: it lifts the float just below 0.5 to 1 and
odd integers past 2^23 up by one.
Input
Constructors
| Input | |
Fields
| |
Constructors
| KeyBackspace | |
| KeyDelete | |
| KeyEnter | |
| KeyEscape | |
| KeyTab | |
| KeyLeft | |
| KeyRight | |
| KeyUp | |
| KeyDown | |
| KeyHome | |
| KeyEnd |
Instances
emptyInput :: Input Source #
inputPointerHeld :: Input -> Bool Source #
appendInputKey :: Key -> SmallArray Key -> SmallArray Key Source #
appendDropEvent :: DropEvent -> SmallArray DropEvent -> SmallArray DropEvent Source #
The drops with one more at the end.
inputKeysElem :: Key -> SmallArray Key -> Bool Source #
inputKeysFromList :: [Key] -> SmallArray Key Source #
inputKeysNull :: SmallArray Key -> Bool Source #
foldInputKeys :: (a -> Key -> a) -> a -> SmallArray Key -> a Source #
Damage
Constructors
| DamageFull | |
| DamageClip Rect |
data DamageBounds Source #
Invalidation bounding strategy for a widget and its interaction events.
Constructors
| DamageSelf | Exact layout bounding box Rect |
| DamageInflated !Float | Layout bounding box inflated by margin (focus rings, shadows, text slop) |
| DamageExact !Rect | Explicit rectangle in window space |
| DamageCustom (Rect -> Rect) | Custom transformation on layout bounding box |
| DamageUnion !DamageBounds !DamageBounds | Combined invalidation bounds |
| DamageNone | No invalidation bounds |
Instances
| Eq DamageBounds Source # | |
Defined in NanoUI.Types | |
| Show DamageBounds Source # | |
Defined in NanoUI.Types Methods showsPrec :: Int -> DamageBounds -> ShowS # show :: DamageBounds -> String # showList :: [DamageBounds] -> ShowS # | |
defaultDamageSlop :: Float Source #
Standard damage slop for text overhang, focus rings, and border anti-aliasing.
sliderDamageSlop :: Float Source #
Damage slop for slider handles that extend past track bounds.
haloDamageSlop :: Float Source #
Damage slop for window resize halos and shadows.
resolveDamageRect :: DamageBounds -> Rect -> Rect Source #
Resolve damage bounds against a given layout rect.
damageWidgetNow :: forall (es :: [Effect]). Ui :> es => WidgetId -> DamageBounds -> Eff es () Source #
damageKeyNow :: forall (es :: [Effect]). Ui :> es => Int -> DamageBounds -> Eff es () Source #
damageGroupNow :: forall (es :: [Effect]). Ui :> es => [WidgetId] -> DamageBounds -> Eff es () Source #
Backend support
data FontMetrics Source #
Constructors
| FontMetrics | |
Fields
| |
data FontBackend Source #
Text preparation performs font queries in IO and returns an immutable snapshot for pure layout. Rasterisation is separate and occurs during draw.
Constructors
| FontBackend | |
Fields
| |
prepareFontMetrics :: FontMetrics -> Text -> IO FontMetrics Source #
prepareFontMetricsMany :: FontMetrics -> [Text] -> IO FontMetrics Source #
Prepare a finite text workspace for pure multi-label layout algorithms.
measureTextIO :: FontMetrics -> Text -> IO (Float, Float) Source #
lineWidthIO :: FontMetrics -> Text -> IO Float Source #
drawShaped :: FontMetrics -> Text -> IO (Maybe ShapedGlyphs) Source #
The glyph quads of a shaped line, placing glyphs in the host's atlas as
needed; Nothing when the host does not shape.
Constructors
| GlyphQuad | |
Instances
data ShapedText Source #
A line of text as the host's shaper laid it out: glyphs chosen and placed with the font's kerning, ligatures and contextual forms, in fallback fonts where the font lacks a character, and right-to-left runs reordered.
Constructors
| ShapedText | |
Fields
| |
Instances
| Eq ShapedText Source # | |
Defined in NanoUI.Font | |
| Show ShapedText Source # | |
Defined in NanoUI.Font Methods showsPrec :: Int -> ShapedText -> ShowS # show :: ShapedText -> String # showList :: [ShapedText] -> ShowS # | |
newtype ShapedGlyphs Source #
The glyph quads that draw a shaped line: eight numbers a glyph (x, y, width and height from the pen, then the atlas UVs u0 v0 u1 v1), in logical pixels. Valid until the host's glyph atlas next resets.
Constructors
| ShapedGlyphs (PrimArray Float) |
Instances
| Eq ShapedGlyphs Source # | |
Defined in NanoUI.Font | |
| Show ShapedGlyphs Source # | |
Defined in NanoUI.Font Methods showsPrec :: Int -> ShapedGlyphs -> ShowS # show :: ShapedGlyphs -> String # showList :: [ShapedGlyphs] -> ShowS # | |
scaleFontMetrics :: Float -> FontMetrics -> FontMetrics Source #
monospaceMetrics :: Float -> FontMetrics Source #
uiFontMetrics :: forall (es :: [Effect]). Ui :> es => Eff es FontMetrics Source #
widgetContentInset :: FontMetrics -> (Float, Float) Source #
widgetPadding :: FontMetrics -> (Float, Float) Source #
treeItemPadding :: FontMetrics -> (Float, Float) Source #
data ScrollBarSlot Source #
The layout arena stores a scroller's slot as its Enum value, and every
other node reads a zero there, so ScrollBarList comes first.
Constructors
| ScrollBarList | |
| ScrollBarPage | |
| ScrollBarWindow |
Instances
| Eq ScrollBarSlot Source # | |
Defined in NanoUI.Font Methods (==) :: ScrollBarSlot -> ScrollBarSlot -> Bool # (/=) :: ScrollBarSlot -> ScrollBarSlot -> Bool # | |
| Enum ScrollBarSlot Source # | |
Defined in NanoUI.Font Methods succ :: ScrollBarSlot -> ScrollBarSlot # pred :: ScrollBarSlot -> ScrollBarSlot # toEnum :: Int -> ScrollBarSlot # fromEnum :: ScrollBarSlot -> Int # enumFrom :: ScrollBarSlot -> [ScrollBarSlot] # enumFromThen :: ScrollBarSlot -> ScrollBarSlot -> [ScrollBarSlot] # enumFromTo :: ScrollBarSlot -> ScrollBarSlot -> [ScrollBarSlot] # enumFromThenTo :: ScrollBarSlot -> ScrollBarSlot -> ScrollBarSlot -> [ScrollBarSlot] # | |
| Show ScrollBarSlot Source # | |
Defined in NanoUI.Font Methods showsPrec :: Int -> ScrollBarSlot -> ShowS # show :: ScrollBarSlot -> String # showList :: [ScrollBarSlot] -> ShowS # | |
scrollBarGutter :: ScrollBarSlot -> Float -> Float Source #
Space an overflowing scroller takes from its content, beside the padding
trailPad on the bar's side, so the content stops one gap before the bar.
A list bar keeps a gap to its well's edge as well. A page bar sits a side
gap inside the page's edge. A window body's bar sits out in the window's
padding, a side gap inside the window's edge, so that padding is the gap
and only the bar and the side gap come out of the content.
scrollBarWidth :: Float Source #
Thickness of a list or page scrollbar.
windowMargin :: Float Source #
A Compact contains fully evaluated, pure, immutable data.
Compact serves two purposes:
- Data stored in a
Compacthas no garbage collection overhead. The garbage collector considers the wholeCompactto be alive if there is a reference to any object within it. - A
Compactcan be serialized, stored, and deserialized again. The serialized data can only be deserialized by the exact binary that created it, but it can be stored indefinitely before deserialization.
Compacts are self-contained, so compacting data involves copying
it; if you have data that lives in two Compacts, each will have a
separate copy of the data.
The cost of compaction is fully evaluating the data + copying it. However,
because compact does not stop-the-world, retaining internal sharing during
the compaction process is very costly. The user can choose whether to
compact or compactWithSharing.
When you have a , you can get a pointer to the actual object
in the region using Compact agetCompact. The Compact type
serves as handle on the region itself; you can use this handle
to add data to a specific Compact with compactAdd or
compactAddWithSharing (giving you a new handle which corresponds
to the same compact region, but points to the newly added object
in the region). At the moment, due to technical reasons,
it's not possible to get the if you only have an Compact aa,
so make sure you hold on to the handle as necessary.
Data in a compact doesn't ever move, so compacting data is also a way to pin arbitrary data structures in memory.
There are some limitations on what can be compacted:
- Functions. Compaction only applies to data.
- Pinned
ByteArray#objects cannot be compacted. This is for a good reason: the memory is pinned so that it can be referenced by address (the address might be stored in a C data structure, for example), so we can't make a copy of it to store in theCompact. - Objects with mutable pointer fields (e.g.
IORef,MutableArray) also cannot be compacted, because subsequent mutation would destroy the property that a compact is self-contained.
If compaction encounters any of the above, a CompactionFailed
exception will be thrown by the compaction operation.