vty-ui-1.7: An interactive terminal user interface library for Vty

Safe HaskellNone

Graphics.Vty.Widgets.Core

Contents

Description

This module is the core of this library; it provides infrastructure for creating new types of widgets and extending their functionality. This module provides various bits of infrastructure, including:

  • modeling user interface widgets
  • managing changes in focus between widgets
  • managing widget state

This module does not provide any concrete widget types. For in-depth discussion on this module's API and widget implementation in particular, see the Vty-ui User's Manual.

Synopsis

Widget Infrastructure

data WidgetImpl a Source

The type of widget implementations, parameterized on the type of the widget's state.

Constructors

WidgetImpl 

Fields

state :: !a

The state of the widget.

visible :: !Bool

Whether the widget is visible.

render_ :: Widget a -> DisplayRegion -> RenderContext -> IO Image

The rendering routine of the widget. Takes the widget itself, a region indicating how much space the rendering process has to work with, and a rendering context to be used to determine attribute and skin settings. This MUST return an image which is no larger than the specified rendering region.

growHorizontal_ :: a -> IO Bool

Returns whether the widget will automatically grow to fill available horizontal space.

growVertical_ :: a -> IO Bool

Returns whether the widget will automatically grow to fill available vertical space.

currentSize :: DisplayRegion

The size of the widget after its most recent rendering pass.

currentPosition :: DisplayRegion

The position of the widget after its most recent rendering pass.

normalAttribute :: Attr

The normal (unfocused) attribute of the wiget.

focusAttribute :: Attr

The focused attribute of the widget.

setCurrentPosition_ :: Widget a -> DisplayRegion -> IO ()

Sets the current position of the widget. Takes a widget reference and a display region indicating the coordinates of the widget's upper left corner.

keyEventHandler :: Widget a -> Key -> [Modifier] -> IO Bool

The widget's key event handler. Takes a widget reference, a key event, and a list of keyboard modifiers. Returns whether the keyboard event was handled. True indicates that the event was handled and that event processing should halt; False indicates that other event handlers, if present, may handle the event.

gainFocusHandlers :: Handlers (Widget a)

List of handlers to be invoked when the widget gains focus.

resizeHandlers :: Handlers (DisplayRegion, DisplayRegion)

List of handlers to be invoked when the widget's size changes.

loseFocusHandlers :: Handlers (Widget a)

List of handlers to be invoked when the widget loses focus.

focused :: Bool

Whether the widget is focused.

getCursorPosition_ :: Widget a -> IO (Maybe DisplayRegion)

Returns the current terminal cursor position. Should return Nothing if the widget does not need to show a cursor, or Just if it does. (For example, widgets receiving keyboard input for text editing would should a cursor, but most won't need to.)

getNormalAttr :: RenderContext -> AttrSource

Get the normal attribute of a rendering context.

defaultContext :: RenderContextSource

Default context settings.

updateWidget :: Widget a -> (WidgetImpl a -> WidgetImpl a) -> IO ()Source

Given a widget and an implementation transformer, apply the transformer to the widget's implementation.

updateWidgetState :: Widget a -> (a -> a) -> IO ()Source

Apply a state transformation function to a widget's state.

newWidget :: a -> (WidgetImpl a -> WidgetImpl a) -> IO (Widget a)Source

Create a new widget. Takes an initial state value and a widget implementation transformation and passes it an implementation with default values.

getState :: Widget a -> IO aSource

Get the state value of a widget.

getCurrentSize :: Widget a -> IO DisplayRegionSource

Get the current size of the widget (its size after its most recent rendering).

setCurrentPosition :: Widget a -> DisplayRegion -> IO ()Source

Set the current position of a widget. Exported for internal use.

getCurrentPosition :: Widget a -> IO DisplayRegionSource

Set the current position of a widget.

growVertical :: Widget a -> IO BoolSource

Does a widget grow vertically?

growHorizontal :: Widget a -> IO BoolSource

Does a widget grow horizontally?

getCursorPosition :: Widget a -> IO (Maybe DisplayRegion)Source

Get the desired cursor position, if any, for a widget.

showWidget :: Show a => Widget a -> IO StringSource

Show a widget. Most widget show instances aren't going to contain all of the widget state, but this at least gives an indication of the widget type, which can be crucial for debugging.

getVisible :: Widget a -> IO BoolSource

Get the visibility of a widget.

setVisible :: Widget a -> Bool -> IO ()Source

Set the visibility of a widget. Invisible widgets do not grow in either direction, always render to an empty image, and never declare a cursor position.

(<~) :: (a -> b) -> IORef a -> IO bSource

Convenience projection on the contents of an IORef.

(<~~) :: (a -> b) -> Widget a -> IO bSource

Convenience projection on the state of a widget.

Rendering

data RenderContext Source

Context information used during the rendering process.

Constructors

RenderContext 

Fields

normalAttr :: Attr

The default normal attribute to use unless overridden by a given widget.

focusAttr :: Attr

The default focused attribute to use for a focused widget unless overridden by a given widget.

overrideAttr :: Attr

An override attribute to be used to override both the normal and focus attributes in effect during rendering. Usually def_attr, this attribute is used when child widgets need to have their attributes overridden by a parent widget.

skin :: Skin

The skin to use for rendering borders and other interface elements which use the skin for their representations.

data RenderError Source

Render errors.

Constructors

ImageTooBig String DisplayRegion DisplayRegion

An error indicating that a widget rendered to an image which exceeded the available space. Provides a representation of the violating widget, the size of the available space, and the size of the image which the widget's rendering routine produced.

renderSource

Arguments

:: Show a 
=> Widget a

The widget to render.

-> DisplayRegion

The amount of space in which to render the widget.

-> RenderContext

The rendering context to use.

-> IO Image 

Render a widget. This function should be called by widget implementations, since it does more than render_; this function takes care of setting up attributes in the rendering context, setting the size of the widget after it has been rendered, and checking for size violations. May throw a RenderError.

renderAndPositionSource

Arguments

:: Show a 
=> Widget a

The widget to render.

-> DisplayRegion

The position at which to render the widget.

-> DisplayRegion

The amount of space in which to render the widget.

-> RenderContext

The rendering context to use.

-> IO Image 

Render a widget and set its position after rendering is complete. This is exported for internal use; widget implementations should call render instead.

Miscellaneous

class HasNormalAttr w whereSource

The class of types with a ''normal'' attribute.

Methods

setNormalAttribute :: w -> Attr -> IO ()Source

class HasFocusAttr w whereSource

The class of types with a ''focus'' attribute, i.e., a way of visually indicating that the object has input focus.

Methods

setFocusAttribute :: w -> Attr -> IO ()Source

withNormalAttribute :: HasNormalAttr w => Attr -> w -> IO wSource

Set the normal attribute on a value.

withFocusAttribute :: HasFocusAttr w => Attr -> w -> IO wSource

Set the focus attribute on a value.

Events

handleKeyEvent :: Widget a -> Key -> [Modifier] -> IO BoolSource

Given a widget and key event information, invoke the widget's key event handler with the event information. Returns whether the event was handled.

onKeyPressed :: Widget a -> (Widget a -> Key -> [Modifier] -> IO Bool) -> IO ()Source

Given a widget and a key event handler, add the handler to the widget's key event handler structure. The event handler is added last, so any preexisting handlers will run before this one.

onGainFocus :: Widget a -> (Widget a -> IO ()) -> IO ()Source

Given a widget and a focus gain event handler, add the handler to the widget. The handler will be invoked when the widget receives focus.

onLoseFocus :: Widget a -> (Widget a -> IO ()) -> IO ()Source

Given a widget and a focus loss event handler, add the handler to the widget. The handler will be invoked when the widget loses focus.

onResize :: Widget a -> ((DisplayRegion, DisplayRegion) -> IO ()) -> IO ()Source

Given a widget and a resize event handler, add the handler to the widget. The handler will be invoked when the widget's size changes. This includes the first rendering, at which point its size changes from (0, 0). Note that if the resize handler needs to change the visual appearance of the widget when its size changes, be sure to use schedule to ensure that visual changes are reflected immediately, and be absolutely sure that those changes will not cause further size changes; that will cause a resize event handler loop that will consume your CPU!

relayKeyEvents :: Widget a -> Widget b -> IO ()Source

Given widgets A and B, causes any key events on widget A to be relayed to widget B. Note that this does behavior constitutes an ordinary key event handler from A's perspective, so if B does not handle a given key event, subsequent key event handlers on A will still get a chance to handle the event. This function is mostly useful for wrapper widgets which don't do any event handling of their own but want to ensure that all key events are relayed to the wrapped widget.

relayFocusEvents :: Widget a -> Widget b -> IO ()Source

Given widgets A and B, cause all focus gain and loss events on A to cause focus gain and loss for B.

Focus management

data FocusGroup Source

Focus group. Represents an cycle of widgets which receive input focus.

data FocusGroupError Source

Focus group handling errors.

Constructors

FocusGroupEmpty

Thrown when the desired operation could not be completed because the focus group is empty.

FocusGroupBadIndex Int

Thrown when the specified focus group entry index was invalid.

newFocusGroup :: IO (Widget FocusGroup)Source

Create a new focus group. Note that the focus group is itself a widget; any input event handlers added to the focus group will fire before input events are handled by the currently-focused widget.

mergeFocusGroups :: Widget FocusGroup -> Widget FocusGroup -> IO (Widget FocusGroup)Source

Merge two focus groups. Given two focus groups A and B, this returns a new focus group with all of the entries from A and B added to it, in that order. At least one A and B must be non-empty or FocusGroupEmpty will be thrown.

appendFocusGroup :: Widget FocusGroup -> Widget FocusGroup -> IO ()Source

Given two focus groups A and B, append the entries of B to A, mutating A in the process. Throws FocusGroupEmpty if B is empty.

resetFocusGroup :: Widget FocusGroup -> IO ()Source

Reset a focus group. This ensures that the focus group's state is coherent by calling focus on the group's focused entry and unfocus on all the rest. This is for internal use, but is used by the Collection switching implementation to ensure that focus state is sane.

addToFocusGroup :: Show a => Widget FocusGroup -> Widget a -> IO (Widget FocusEntry)Source

Add a widget to a focus group. This returns a focus group entry which wraps the specified widget; the focus group entry is also a widget and can take key event handlers and the like. During input event processing, the focus group entry receives keyboard events and passes them on to the wrapped widget. If you want a widget to have specific event handling in a particular interface, add event handlers to its focus entry/entries instead of the widget itself.

focusNext :: Widget FocusGroup -> IO ()Source

Focus the next widget in a focus group.

focusPrevious :: Widget FocusGroup -> IO ()Source

Focus the previous widget in a focus group.

setFocusGroupNextKey :: Widget FocusGroup -> Key -> [Modifier] -> IO ()Source

Set the keyboard event information used to change focus to the next widget in a focus group.

setFocusGroupPrevKey :: Widget FocusGroup -> Key -> [Modifier] -> IO ()Source

Set the keyboard event information used to change focus to the previous widget in a focus group.

focus :: Widget a -> IO ()Source

Focus a widget. Causes its focus gain event handlers to run. If the widget is in a FocusGroup and if that group's currently-focused widget is some other widget, that widget will lose the focus and its focus loss event handlers will be called.

unfocus :: Widget a -> IO ()Source

Unfocus a widget. Causes its focus loss event handlers to run.