From 68a8eb786ced7a4b95819ba4218df0935482e3b2 Mon Sep 17 00:00:00 2001 From: Francisco Vallarino Date: Thu, 12 Aug 2021 23:43:39 -0300 Subject: [PATCH] Export configuration types to have Haddock generate documentation --- .gitignore | 1 + monomer.cabal | 2 +- package.yaml | 2 +- src/Monomer/Core/Combinators.hs | 5 +- src/Monomer/Graphics/RemixIcon.hs | 2 +- src/Monomer/Widgets/Animation/Fade.hs | 18 ++- src/Monomer/Widgets/Animation/Slide.hs | 20 ++- src/Monomer/Widgets/Composite.hs | 145 +++++++++++------- src/Monomer/Widgets/Container.hs | 14 +- src/Monomer/Widgets/Containers/Alert.hs | 42 ++--- src/Monomer/Widgets/Containers/Box.hs | 73 +++++---- src/Monomer/Widgets/Containers/Confirm.hs | 52 ++++--- src/Monomer/Widgets/Containers/Draggable.hs | 40 +++-- src/Monomer/Widgets/Containers/DropTarget.hs | 18 ++- src/Monomer/Widgets/Containers/Dropdown.hs | 47 +++--- src/Monomer/Widgets/Containers/Grid.hs | 12 +- src/Monomer/Widgets/Containers/Keystroke.hs | 22 +-- src/Monomer/Widgets/Containers/Scroll.hs | 55 ++++--- src/Monomer/Widgets/Containers/SelectList.hs | 67 ++++---- src/Monomer/Widgets/Containers/Split.hs | 34 ++-- src/Monomer/Widgets/Containers/Stack.hs | 25 +-- src/Monomer/Widgets/Containers/ThemeSwitch.hs | 18 ++- src/Monomer/Widgets/Containers/Tooltip.hs | 24 +-- src/Monomer/Widgets/Containers/ZStack.hs | 22 +-- src/Monomer/Widgets/Single.hs | 7 +- .../Widgets/Singles/Base/InputField.hs | 17 +- src/Monomer/Widgets/Singles/Button.hs | 45 +++--- src/Monomer/Widgets/Singles/Checkbox.hs | 40 ++--- src/Monomer/Widgets/Singles/ColorPicker.hs | 70 +++++---- src/Monomer/Widgets/Singles/DateField.hs | 56 ++++--- src/Monomer/Widgets/Singles/Dial.hs | 39 +++-- src/Monomer/Widgets/Singles/ExternalLink.hs | 43 +++--- src/Monomer/Widgets/Singles/Icon.hs | 15 +- src/Monomer/Widgets/Singles/Image.hs | 45 +++--- src/Monomer/Widgets/Singles/Label.hs | 39 +++-- .../Widgets/Singles/LabeledCheckbox.hs | 63 ++++---- src/Monomer/Widgets/Singles/LabeledRadio.hs | 61 ++++---- src/Monomer/Widgets/Singles/NumericField.hs | 52 ++++--- src/Monomer/Widgets/Singles/Radio.hs | 35 +++-- src/Monomer/Widgets/Singles/SeparatorLine.hs | 15 +- src/Monomer/Widgets/Singles/Slider.hs | 51 +++--- src/Monomer/Widgets/Singles/Spacer.hs | 15 +- src/Monomer/Widgets/Singles/TextArea.hs | 40 ++--- src/Monomer/Widgets/Singles/TextDropdown.hs | 35 ++--- src/Monomer/Widgets/Singles/TextField.hs | 44 +++--- src/Monomer/Widgets/Singles/TimeField.hs | 56 ++++--- src/Monomer/Widgets/Util/Style.hs | 6 +- 47 files changed, 928 insertions(+), 721 deletions(-) diff --git a/.gitignore b/.gitignore index 968ef7dd..95cb10b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .stack-work/ .vscode/ haddock/ +dist-docs.*/ *~ *.aux *.hp diff --git a/monomer.cabal b/monomer.cabal index 722aed1b..ddc3cfbb 100644 --- a/monomer.cabal +++ b/monomer.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: monomer -version: 1.0.0.0 +version: 1.0.0.1 synopsis: A GUI library for writing native Haskell applications. description: Monomer is an easy to use, cross platform, GUI library for writing native Haskell applications. diff --git a/package.yaml b/package.yaml index 6f54ae8d..43375107 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: monomer -version: 1.0.0.0 +version: 1.0.0.1 github: fjvallarino/monomer license: BSD3 author: Francisco Vallarino diff --git a/src/Monomer/Core/Combinators.hs b/src/Monomer/Core/Combinators.hs index 58108074..5fd023fd 100644 --- a/src/Monomer/Core/Combinators.hs +++ b/src/Monomer/Core/Combinators.hs @@ -500,11 +500,12 @@ class CmbSizeReqH t where class CmbSizeReqUpdater t where sizeReqUpdater :: ((SizeReq, SizeReq) -> (SizeReq, SizeReq)) -> t --- | Resize factor combinator. +-- | Resize factor combinator. A value of 0 represents fixed size. class CmbResizeFactor t where resizeFactor :: Double -> t --- | Resize factor combinator for individual w and h components. +-- | Resize factor combinator for individual w and h components. A value of 0 +-- represents fixed size. class CmbResizeFactorDim t where resizeFactorW :: Double -> t resizeFactorH :: Double -> t diff --git a/src/Monomer/Graphics/RemixIcon.hs b/src/Monomer/Graphics/RemixIcon.hs index 34bce50a..3cd202d2 100644 --- a/src/Monomer/Graphics/RemixIcon.hs +++ b/src/Monomer/Graphics/RemixIcon.hs @@ -10,7 +10,7 @@ Utility functions to retrieve the Unicode code point of a Remix Font using its representative name. These code points can be used in labels or buttons to show icons instead of regular text. -Make sure to load the remixicon.ttf font in your application and set `textFont` +Make sure to load the remixicon.ttf font in your application and set 'textFont' in the corresponding widget. Existing icons can be browsed in https://remixicon.com. diff --git a/src/Monomer/Widgets/Animation/Fade.hs b/src/Monomer/Widgets/Animation/Fade.hs index 69e6a17e..81ed4c66 100644 --- a/src/Monomer/Widgets/Animation/Fade.hs +++ b/src/Monomer/Widgets/Animation/Fade.hs @@ -8,15 +8,9 @@ Portability : non-portable Fade animation widget. Wraps a child widget whose content will be animated. -Config: - -- autoStart: whether the first time the widget is added, animation should run. -- duration: how long the animation lasts in ms. -- onFinished: event to raise when animation is complete. - Messages: -- Receives a 'AnimationMsg', used to control the state of the animation. +- Accepts an 'AnimationMsg', used to control the state of the animation. -} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} @@ -25,6 +19,9 @@ Messages: {-# LANGUAGE OverloadedStrings #-} module Monomer.Widgets.Animation.Fade ( + -- * Configuration + FadeCfg, + -- * Constructors animFadeIn, animFadeIn_, animFadeOut, @@ -47,6 +44,13 @@ import Monomer.Widgets.Animation.Types import qualified Monomer.Lens as L +{-| +Configuration options for fade: + +- 'autoStart': whether the first time the widget is added, animation should run. +- 'duration': how long the animation lasts in ms. +- 'onFinished': event to raise when animation is complete. +-} data FadeCfg e = FadeCfg { _fdcAutoStart :: Maybe Bool, _fdcDuration :: Maybe Int, diff --git a/src/Monomer/Widgets/Animation/Slide.hs b/src/Monomer/Widgets/Animation/Slide.hs index 8eae2331..610c4af9 100644 --- a/src/Monomer/Widgets/Animation/Slide.hs +++ b/src/Monomer/Widgets/Animation/Slide.hs @@ -8,16 +8,9 @@ Portability : non-portable Slide animation widget. Wraps a child widget whose content will be animated. -Config: - -- autoStart: whether the first time the widget is added, animation should run. -- duration: how long the animation lasts in ms. -- onFinished: event to raise when animation is complete. -- Individual combinators for direction. - Messages: -- Receives a 'AnimationMsg', used to control the state of the animation. +- Accepts a 'AnimationMsg', used to control the state of the animation. -} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} @@ -25,6 +18,9 @@ Messages: {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Animation.Slide ( + -- * Configuration + SlideCfg, + -- * Constructors animSlideIn, animSlideIn_, animSlideOut, @@ -58,6 +54,14 @@ data SlideDirection | SlideDown deriving (Eq, Show) +{-| +Configuration options for slide: + +- 'autoStart': whether the first time the widget is added, animation should run. +- 'duration': how long the animation lasts in ms. +- 'onFinished': event to raise when animation is complete. +- Individual combinators for direction. +-} data SlideCfg e = SlideCfg { _slcDirection :: Maybe SlideDirection, _slcAutoStart :: Maybe Bool, diff --git a/src/Monomer/Widgets/Composite.hs b/src/Monomer/Widgets/Composite.hs index 59ff6ba6..3bf78455 100644 --- a/src/Monomer/Widgets/Composite.hs +++ b/src/Monomer/Widgets/Composite.hs @@ -7,9 +7,9 @@ Stability : experimental Portability : non-portable Composite widget. Main glue between all the other widgets, also acts as the main -app widget. Composite allows to split an application into reusable partss -without the need to implement a lower level widget. It can comunicate with its -parent component by reporting events. +app widget. Composite allows to split an application into reusable parts without +the need to implement a lower level widget. It can comunicate with its parent +component by reporting events. Requires two main functions: @@ -18,26 +18,6 @@ and model. This widget tree is made of other widgets, in general combinations of containers and singles. - Event Handler: processes user defined events which are raised by the widgets created when building the UI. - -Configs: - -- mergeRequired: indicates if merging is necessary for this widget. In case the -UI build process references information outside the model, it can be used to -signal that merging is required even if the model has not changed. It can also -be used as a performance tweak if the changes do not require rebuilding the UI. -- onInit: event to raise when the widget is created. Useful for performing all -kinds of initialization. -- onDispose: event to raise when the widget is disposed. Used to free resources. -- onResize: event to raise when the size of the widget changes. -- onChange: event to raise when the size of the model changes. -- onChangeReq: WidgetRequest to generate when the size of the widget changes. -- onEnabledChange: event to raise when the enabled status changes. -- onVisibleChange: event to raise when the visibility changes. -- compositeMergeReqs: functions to generate WidgetRequests during the merge -process. Since merge is already handled by Composite (by merging its tree), this -is complementary for the cases when it's required. For example, it is used in -'Monomer.Widgets.Containers.Confirm' to set the focus on its Accept button when -visibility is restored (usually means it was brought to the front in a zstack). -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ExistentialQuantification #-} @@ -48,16 +28,27 @@ visibility is restored (usually means it was brought to the front in a zstack). {-# LANGUAGE ScopedTypeVariables #-} module Monomer.Widgets.Composite ( + -- * Re-exported modules module Monomer.Core, module Monomer.Event, module Monomer.Widgets.Util, + -- * Configuration CompositeCfg, EventResponse(..), + CompParentModel, + CompositeModel, + CompositeEvent, + MergeRequired, MergeReqsHandler, EventHandler, UIBuilder, + TaskHandler, + ProducerHandler, + CompMsgUpdate, compositeMergeReqs, + + -- * Constructors composite, composite_, compositeV, @@ -93,27 +84,41 @@ import Monomer.Widgets.Util import qualified Monomer.Core.Lens as L -- | Type of the parent's model -type ParentModel sp = Typeable sp +type CompParentModel sp = Typeable sp -- | Type of the composite's model type CompositeModel s = (Eq s, WidgetModel s) -- | Type of the composite's event type CompositeEvent e = WidgetEvent e +-- | Checks if merging the composite is required. +type MergeRequired s = s -> s -> Bool + -- | Generates requests during the merge process. type MergeReqsHandler s e - = WidgetEnv s e -> WidgetNode s e -> WidgetNode s e -> s -> [WidgetRequest s e] + = WidgetEnv s e + -> WidgetNode s e + -> WidgetNode s e + -> s + -> [WidgetRequest s e] + -- | Handles a composite event and returns a set of responses. type EventHandler s e sp ep - = WidgetEnv s e -> WidgetNode s e -> s -> e -> [EventResponse s e sp ep] + = WidgetEnv s e + -> WidgetNode s e + -> s + -> e + -> [EventResponse s e sp ep] + -- | Creates the widget tree based on the given model. type UIBuilder s e = WidgetEnv s e -> s -> WidgetNode s e --- | Checks if merging the composite is required. -type MergeRequired s = s -> s -> Bool + -- | Asynchronous task generating a single event. type TaskHandler e = IO e + -- | Asynchronous task generating multiple events. type ProducerHandler e = (e -> IO ()) -> IO () +-- | Model update function wrapped as a message. data CompMsgUpdate = forall s . CompositeModel s => CompMsgUpdate (s -> s) @@ -125,10 +130,10 @@ data EventResponse s e sp ep | Event e -- | Raises an event that will be handled by the parent. | Report ep - -- | Generates a WidgetRequest. + -- | Generates a 'WidgetRequest'. | Request (WidgetRequest s e) {-| - Generates a WidgetRequest matching the parent's types. Useful when receiving + Generates a 'WidgetRequest' matching the parent's types. Useful when receiving requests as configuration from the parent, since the types will not match otherwise. -} @@ -151,7 +156,31 @@ data EventResponse s e sp ep -} | Producer (ProducerHandler e) --- | Configuration options for composite widget. +{-| +Configuration options for composite: + +- 'mergeRequired': indicates if merging is necessary for this widget. In case + the UI build process references information outside the model, it can be used + to signal that merging is required even if the model has not changed. It can + also be used as a performance tweak if the changes do not require rebuilding + the UI. +- 'onInit': event to raise when the widget is created. Useful for performing all + kinds of initialization. +- 'onDispose': event to raise when the widget is disposed. Used to free + resources. +- 'onResize': event to raise when the size of the widget changes. +- 'onChange': event to raise when the size of the model changes. +- 'onChangeReq': 'WidgetRequest' to generate when the size of the widget + changes. +- 'onEnabledChange': event to raise when the enabled status changes. +- 'onVisibleChange': event to raise when the visibility changes. +- 'compositeMergeReqs': functions to generate WidgetRequests during the merge + process. Since merge is already handled by Composite (by merging its tree), + this is complementary for the cases when it's required. For example, it is + used in 'Monomer.Widgets.Containers.Confirm' to set the focus on its Accept + button when visibility is restored (usually means it was brought to the front + in a zstack). +-} data CompositeCfg s e sp ep = CompositeCfg { _cmcMergeRequired :: Maybe (MergeRequired s), _cmcMergeReqs :: [MergeReqsHandler s e], @@ -270,7 +299,7 @@ data ReducedEvents s e sp ep = ReducedEvents { Creates a composite taking its model from a lens into the parent model. -} composite - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => WidgetType -- ^ The name of the composite. -> ALens' sp s -- ^ The lens into the parent's model. -> UIBuilder s e -- ^ The UI builder function. @@ -284,7 +313,7 @@ Creates a composite taking its model from a lens into the parent model. Accepts config. -} composite_ - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => WidgetType -- ^ The name of the composite. -> ALens' sp s -- ^ The lens into the parent's model. -> UIBuilder s e -- ^ The UI builder function. @@ -297,7 +326,7 @@ composite_ widgetType field uiBuilder evtHandler cfgs = newNode where -- | Creates a composite using the given model and onChange event handler. compositeV - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => WidgetType -- ^ The name of the composite. -> s -- ^ The model. -> (s -> ep) -- ^ The event to report when model changes. @@ -312,7 +341,7 @@ Creates a composite using the given model and onChange event handler. Accepts config. -} compositeV_ - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => WidgetType -- ^ The name of the composite. -> s -- ^ The model. -> (s -> ep) -- ^ The event to report when model changes. @@ -325,9 +354,9 @@ compositeV_ wType val handler uiBuilder evtHandler cfgs = newNode where newCfgs = onChange handler : cfgs newNode = compositeD_ wType widgetData uiBuilder evtHandler newCfgs --- | Creates a color picker providing a WidgetData instance and config. +-- | Creates a composite providing a WidgetData instance and config. compositeD_ - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => WidgetType -- ^ The name of the composite. -> WidgetData sp s -- ^ The model. -> UIBuilder s e -- ^ The UI builder function. @@ -356,7 +385,7 @@ compositeD_ wType wData uiBuilder evtHandler configs = newNode where newNode = defaultWidgetNode wType widget createComposite - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> Widget sp ep @@ -379,7 +408,7 @@ createComposite comp state = widget where -- | Init compositeInit - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -408,7 +437,7 @@ compositeInit comp state wenv widgetComp = newResult where -- | Merge compositeMerge - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -467,7 +496,7 @@ compositeMerge comp state wenv newComp oldComp = newResult where -- | Dispose compositeDispose - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -485,7 +514,7 @@ compositeDispose comp state wenv widgetComp = result where result = toParentResult comp state wenv widgetComp tempResult compositeGetInstanceTree - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -505,7 +534,7 @@ compositeGetInstanceTree comp state wenv node = instTree where -- | Next focusable compositeFindNextFocus - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -522,7 +551,7 @@ compositeFindNextFocus comp state wenv widgetComp dir start = nextFocus where -- | Find compositeFindByPoint - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -543,7 +572,7 @@ compositeFindByPoint comp state wenv widgetComp start point resultInfo = widgetFindByPoint widget cwenv _cpsRoot start point compositeFindBranchByPath - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -565,7 +594,7 @@ compositeFindBranchByPath comp state wenv widgetComp path -- | Event handling compositeHandleEvent - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -591,7 +620,7 @@ compositeHandleEvent comp state wenv widgetComp target evt = result where -- | Message handling compositeHandleMessage - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp, Typeable i) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp, Typeable i) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -614,7 +643,7 @@ compositeHandleMessage comp state@CompositeState{..} wenv widgetComp target arg -- Preferred size compositeGetSizeReq - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -633,7 +662,7 @@ compositeGetSizeReq comp state wenv widgetComp = (newReqW, newReqH) where -- Preferred size updateSizeReq - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -647,7 +676,7 @@ updateSizeReq comp state wenv widgetComp = newComp where -- Resize compositeResize - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -678,7 +707,7 @@ compositeResize comp state wenv widgetComp viewport rszReq = resizedRes where -- Render compositeRender - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -693,7 +722,7 @@ compositeRender comp state wenv widgetComp renderer = action where action = widgetRender widget cwenv _cpsRoot renderer handleMsgEvent - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -712,7 +741,7 @@ handleMsgEvent comp state wenv widgetComp event = newResult where newResult = WidgetResult widgetComp (Seq.fromList (catMaybes newReqs)) handleMsgUpdate - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -730,7 +759,7 @@ handleMsgUpdate comp state wenv widgetComp fnUpdate = result where | otherwise = mergeChild comp state wenv newModel _cpsRoot widgetComp toParentResult - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -750,7 +779,7 @@ toParentResult comp state wenv widgetComp result = newResult where newResult = WidgetResult newNode newReqs evtResponseToRequest - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => WidgetNode sp ep -> WidgetKeyMap s e -> EventResponse s e sp ep @@ -770,7 +799,7 @@ evtResponseToRequest widgetComp widgetKeys response = case response of path = widgetComp ^. L.info . L.path mergeChild - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> CompositeState s e -> WidgetEnv sp ep @@ -797,14 +826,14 @@ mergeChild comp state wenv newModel widgetRoot widgetComp = newResult where & L.requests <>~ Seq.fromList newReqs getModel - :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, ParentModel sp) + :: (CompositeModel s, CompositeEvent e, CompositeEvent ep, CompParentModel sp) => Composite s e sp ep -> WidgetEnv sp ep -> s getModel comp wenv = widgetDataGet (_weModel wenv) (_cmpWidgetData comp) toParentReq - :: (CompositeModel s, ParentModel sp) + :: (CompositeModel s, CompParentModel sp) => WidgetId -> WidgetRequest s e -> Maybe (WidgetRequest sp ep) diff --git a/src/Monomer/Widgets/Container.hs b/src/Monomer/Widgets/Container.hs index 9e8d83a9..fd608f5f 100644 --- a/src/Monomer/Widgets/Container.hs +++ b/src/Monomer/Widgets/Container.hs @@ -14,12 +14,14 @@ Helper for creating widgets with children elements. {-# LANGUAGE ScopedTypeVariables #-} module Monomer.Widgets.Container ( + -- * Re-exported modules module Monomer.Core, module Monomer.Core.Combinators, module Monomer.Event, module Monomer.Graphics, module Monomer.Widgets.Util, + -- * Configuration ContainerGetBaseStyle, ContainerGetCurrentStyle, ContainerUpdateCWenvHandler, @@ -37,10 +39,11 @@ module Monomer.Widgets.Container ( ContainerGetSizeReqHandler, ContainerResizeHandler, ContainerRenderHandler, - Container(..), - createContainer, - updateWenvOffset + updateWenvOffset, + + -- * Constructors + createContainer ) where import Control.Applicative ((<|>)) @@ -126,8 +129,9 @@ type ContainerInitHandler s e {-| Allows making further operations after children have been initialized. -Note: if state was modified on `init`, you should use the new state provided as -an argument, since the state referenced in the closure will be outdated. +Note: if state was modified on 'containerInit', you should use the new state +provided as an argument, since the state referenced in the closure will be +outdated. -} type ContainerInitPostHandler s e a = WidgetEnv s e -- ^ The widget environment. diff --git a/src/Monomer/Widgets/Containers/Alert.hs b/src/Monomer/Widgets/Containers/Alert.hs index 926b4e41..5a7614f4 100644 --- a/src/Monomer/Widgets/Containers/Alert.hs +++ b/src/Monomer/Widgets/Containers/Alert.hs @@ -8,13 +8,11 @@ Portability : non-portable Simple alert dialog, displaying a close button and optional title. Usually embedded in a zstack component and displayed/hidden depending on context. - -Config: - -- titleCaption: the title of the alert dialog. -- closeCaption: the caption of the close button. -} module Monomer.Widgets.Containers.Alert ( + -- * Configuration + AlertCfg, + -- * Constructors alert, alert_, alertMsg, @@ -41,6 +39,12 @@ import Monomer.Widgets.Singles.Spacer import qualified Monomer.Lens as L +{-| +Configuration options for alert: + +- 'titleCaption': the title of the alert dialog. +- 'closeCaption': the caption of the close button. +-} data AlertCfg = AlertCfg { _alcTitle :: Maybe Text, _alcClose :: Maybe Text @@ -73,19 +77,19 @@ instance CmbCloseCaption AlertCfg where -- | Creates an alert dialog with the provided content. alert - :: (WidgetModel sp, WidgetEvent ep) - => ep -- ^ The event to raise when the dialog is closed. - -> WidgetNode () ep -- ^ The content to display in the dialog. - -> WidgetNode sp ep -- ^ The created dialog. + :: (WidgetModel s, WidgetEvent e) + => e -- ^ The event to raise when the dialog is closed. + -> WidgetNode () e -- ^ The content to display in the dialog. + -> WidgetNode s e -- ^ The created dialog. alert evt dialogBody = alert_ evt def dialogBody -- | Creates an alert dialog with the provided content. Accepts config. alert_ - :: (WidgetModel sp, WidgetEvent ep) - => ep -- ^ The event to raise when the dialog is closed. + :: (WidgetModel s, WidgetEvent e) + => e -- ^ The event to raise when the dialog is closed. -> [AlertCfg] -- ^ The config options for the dialog. - -> WidgetNode () ep -- ^ The content to display in the dialog. - -> WidgetNode sp ep -- ^ The created dialog. + -> WidgetNode () e -- ^ The content to display in the dialog. + -> WidgetNode s e -- ^ The created dialog. alert_ evt configs dialogBody = newNode where config = mconcat configs createUI = buildUI (const dialogBody) evt config @@ -93,19 +97,19 @@ alert_ evt configs dialogBody = newNode where -- | Creates an alert dialog with a text message as content. alertMsg - :: (WidgetModel sp, WidgetEvent ep) + :: (WidgetModel s, WidgetEvent e) => Text -- ^ The message to display. - -> ep -- ^ The event to raise when the dialog is closed. - -> WidgetNode sp ep -- ^ The created dialog. + -> e -- ^ The event to raise when the dialog is closed. + -> WidgetNode s e -- ^ The created dialog. alertMsg message evt = alertMsg_ message evt def -- | Creates an alert dialog with a text message as content. Accepts config. alertMsg_ - :: (WidgetModel sp, WidgetEvent ep) + :: (WidgetModel s, WidgetEvent e) => Text -- ^ The message to display. - -> ep -- ^ The event to raise when the dialog is closed. + -> e -- ^ The event to raise when the dialog is closed. -> [AlertCfg] -- ^ The config options for the dialog. - -> WidgetNode sp ep -- ^ The created dialog. + -> WidgetNode s e -- ^ The created dialog. alertMsg_ message evt configs = newNode where config = mconcat configs dialogBody wenv = label_ message [multiline] diff --git a/src/Monomer/Widgets/Containers/Box.hs b/src/Monomer/Widgets/Containers/Box.hs index a3861cb9..fc7e74ed 100644 --- a/src/Monomer/Widgets/Containers/Box.hs +++ b/src/Monomer/Widgets/Containers/Box.hs @@ -6,41 +6,19 @@ Maintainer : fjvallarino@gmail.com Stability : experimental Portability : non-portable -Container for a single item. Useful in different layout situations, since it -provides alignment options. This allows for the inner widget to keep its size -while being positioned more explicitly, while the box takes up the complete -space assigned by the container (in particular for containers which do not -follow SizeReq restriccions, such as Grid). +Container for a single item. + +Useful in different layout situations, since it provides alignment options. This +allows for the inner widget to keep its size while being positioned more +explicitly, while the box takes up the complete space assigned by its parent (in +particular for containers which do not follow SizeReq restriccions, such as +Grid). + Can be used to add padding to an inner widget with a border. This is equivalent to the margin property in CSS. + Also useful to handle click events in complex widget structures (for example, a label with an image at its side). - -Config: - -- mergeRequired: function called during merge that receives the old and new - model, returning True in case the child widget needs to be merged. Since by - default merge is required, this function can be used to restrict merging when - it would be expensive and it is not necessary. For example, a list of widgets - representing search result only needs to be updated when the list of results - changes, not while the user inputs new search criteria (which also triggers - a model change and, hence, the merge process). -- ignoreEmptyArea: when the inner widget does not use all the available space, - ignoring the unassigned space allows for mouse events to pass through. This is - useful in zstack layers. -- sizeReqUpdater: allows modifying the 'SizeReq' generated by the inner widget. -- alignLeft: aligns the inner widget to the left. -- alignCenter: aligns the inner widget to the horizontal center. -- alignRight: aligns the inner widget to the right. -- alignTop: aligns the inner widget to the top. -- alignMiddle: aligns the inner widget to the left. -- alignBottom: aligns the inner widget to the bottom. -- onClick: click event. -- onClickReq: generates a WidgetRequest on click. -- onClickEmpty: click event on empty area. -- onClickEmptyReq: generates a WidgetRequest on click in empty area. -- expandContent: if the inner widget should use all the available space. To be - able to use alignment options, this must be False (the default). -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} @@ -48,7 +26,9 @@ Config: {-# LANGUAGE RankNTypes #-} module Monomer.Widgets.Containers.Box ( - BoxCfg(..), + -- * Configuration + BoxCfg, + -- * Constructors box, box_, expandContent @@ -66,7 +46,34 @@ import Monomer.Widgets.Containers.Stack import qualified Monomer.Lens as L --- | Configuration options for box widget. +{-| +Configuration options for box: + +- 'mergeRequired': function called during merge that receives the old and new + model, returning True in case the child widget needs to be merged. Since by + default merge is required, this function can be used to restrict merging when + it would be expensive and it is not necessary. For example, a list of widgets + representing search result only needs to be updated when the list of results + changes, not while the user inputs new search criteria (which also triggers a + model change and, hence, the merge process). +- 'ignoreEmptyArea': when the inner widget does not use all the available space, + ignoring the unassigned space allows for mouse events to pass through. This is + useful in zstack layers. +- 'sizeReqUpdater': allows modifying the 'SizeReq' generated by the inner + widget. +- 'alignLeft': aligns the inner widget to the left. +- 'alignCenter': aligns the inner widget to the horizontal center. +- 'alignRight': aligns the inner widget to the right. +- 'alignTop': aligns the inner widget to the top. +- 'alignMiddle': aligns the inner widget to the left. +- 'alignBottom': aligns the inner widget to the bottom. +- 'onClick': click event. +- 'onClickReq': generates a WidgetRequest on click. +- 'onClickEmpty': click event on empty area. +- 'onClickEmptyReq': generates a WidgetRequest on click in empty area. +- 'expandContent': if the inner widget should use all the available space. To be + able to use alignment options, this must be False (the default). +-} data BoxCfg s e = BoxCfg { _boxExpandContent :: Maybe Bool, _boxIgnoreEmptyArea :: Maybe Bool, diff --git a/src/Monomer/Widgets/Containers/Confirm.hs b/src/Monomer/Widgets/Containers/Confirm.hs index 9b614d55..113671fb 100644 --- a/src/Monomer/Widgets/Containers/Confirm.hs +++ b/src/Monomer/Widgets/Containers/Confirm.hs @@ -9,17 +9,14 @@ Portability : non-portable Simple confirm dialog, displaying an accept and close buttons and optional title. Usually embedded in a zstack component and displayed/hidden depending on context. - -Config: - -- titleCaption: the title of the alert dialog. -- acceptCaption: the caption of the accept button. -- closeCaption: the caption of the close button. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} module Monomer.Widgets.Containers.Confirm ( + -- * Configuration + ConfirmCfg, + -- * Constructors confirm, confirm_, confirmMsg, @@ -46,6 +43,13 @@ import Monomer.Widgets.Singles.Spacer import qualified Monomer.Lens as L +{-| +Configuration options for confirm: + +- 'titleCaption': the title of the alert dialog. +- 'acceptCaption': the caption of the accept button. +- 'closeCaption': the caption of the close button. +-} data ConfirmCfg = ConfirmCfg { _cfcTitle :: Maybe Text, _cfcAccept :: Maybe Text, @@ -90,22 +94,22 @@ newtype ConfirmEvt e -- | Creates a confirm dialog with the provided content. confirm - :: (WidgetModel sp, WidgetEvent ep) - => ep -- ^ The accept button event. - -> ep -- ^ The cancel button event. - -> WidgetNode () (ConfirmEvt ep) -- ^ The content to display in the dialog. - -> WidgetNode sp ep -- ^ The created dialog. + :: (WidgetModel s, WidgetEvent e) + => e -- ^ The accept button event. + -> e -- ^ The cancel button event. + -> WidgetNode () (ConfirmEvt e) -- ^ The content to display in the dialog. + -> WidgetNode s e -- ^ The created dialog. confirm acceptEvt cancelEvt dialogBody = newNode where newNode = confirm_ acceptEvt cancelEvt def dialogBody -- | Creates an alert dialog with the provided content. Accepts config. confirm_ - :: (WidgetModel sp, WidgetEvent ep) - => ep -- ^ The accept button event. - -> ep -- ^ The cancel button event. + :: (WidgetModel s, WidgetEvent e) + => e -- ^ The accept button event. + -> e -- ^ The cancel button event. -> [ConfirmCfg] -- ^ The config options for the dialog. - -> WidgetNode () (ConfirmEvt ep) -- ^ The content to display in the dialog. - -> WidgetNode sp ep -- ^ The created dialog. + -> WidgetNode () (ConfirmEvt e) -- ^ The content to display in the dialog. + -> WidgetNode s e -- ^ The created dialog. confirm_ acceptEvt cancelEvt configs dialogBody = newNode where config = mconcat configs createUI = buildUI (const dialogBody) acceptEvt cancelEvt config @@ -114,21 +118,21 @@ confirm_ acceptEvt cancelEvt configs dialogBody = newNode where -- | Creates an alert dialog with a text message as content. confirmMsg - :: (WidgetModel sp, WidgetEvent ep) + :: (WidgetModel s, WidgetEvent e) => Text -- ^ The message to display in the dialog. - -> ep -- ^ The accept button event. - -> ep -- ^ The cancel button event. - -> WidgetNode sp ep -- ^ The created dialog. + -> e -- ^ The accept button event. + -> e -- ^ The cancel button event. + -> WidgetNode s e -- ^ The created dialog. confirmMsg msg acceptEvt cancelEvt = confirmMsg_ msg acceptEvt cancelEvt def -- | Creates an alert dialog with a text message as content. Accepts config. confirmMsg_ - :: (WidgetModel sp, WidgetEvent ep) + :: (WidgetModel s, WidgetEvent e) => Text -- ^ The message to display in the dialog. - -> ep -- ^ The accept button event. - -> ep -- ^ The cancel button event. + -> e -- ^ The accept button event. + -> e -- ^ The cancel button event. -> [ConfirmCfg] -- ^ The config options for the dialog. - -> WidgetNode sp ep -- ^ The created dialog. + -> WidgetNode s e -- ^ The created dialog. confirmMsg_ message acceptEvt cancelEvt configs = newNode where config = mconcat configs dialogBody wenv = label_ message [multiline] diff --git a/src/Monomer/Widgets/Containers/Draggable.hs b/src/Monomer/Widgets/Containers/Draggable.hs index 2919f5e2..26fd0041 100644 --- a/src/Monomer/Widgets/Containers/Draggable.hs +++ b/src/Monomer/Widgets/Containers/Draggable.hs @@ -9,30 +9,21 @@ Portability : non-portable Draggable container for a single item. Useful for adding drag support without having to implement a custom widget. Usually works in tandem with 'Monomer.Widgets.Containers.DropTarget'. - -The regular styling of this component apply only when the item is not being -dragged. To style the dragged container, use draggableStyle. - -The transparency config only applies to the inner content. - -Config: - -- transparency: the alpha level to apply when rendering content in drag mode. -- maxDim: the maximum size of the largest axis when dragging. Keeps proportions. -- draggableStyle: the style to use when the item is being dragged. -- draggableRender: rendering function for the dragged state. Allows customizing -this step without implementing a custom widget all the lifecycle steps. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Containers.Draggable ( - draggable, - draggable_, + -- * Configuration + DraggableRender, + DraggableCfg, draggableMaxDim, draggableStyle, - draggableRender + draggableRender, + -- * Constructors + draggable, + draggable_ ) where import Control.Applicative ((<|>)) @@ -55,7 +46,22 @@ type DraggableRender s e -> Renderer -- ^ The renderer. -> IO () -- ^ The drawing actions. --- | Configuration options for draggable widget. +{-| +Configuration options for draggable: + +- 'transparency': the alpha level to apply when rendering content in drag mode. +- 'draggableMaxDim': the maximum size of the largest axis when dragging. Keeps + proportions. +- 'draggableStyle': the style to use when the item is being dragged. +- 'draggableRender': rendering function for the dragged state. Allows + customizing this step without implementing a custom widget all the lifecycle + steps. + +The regular styling of this component apply only when the item is not being +dragged. To style the dragged container, use draggableStyle. + +The transparency config only applies to the inner content. +-} data DraggableCfg s e = DraggableCfg { _dgcTransparency :: Maybe Double, _dgcMaxDim :: Maybe Double, diff --git a/src/Monomer/Widgets/Containers/DropTarget.hs b/src/Monomer/Widgets/Containers/DropTarget.hs index 5a4f1edd..f957039e 100644 --- a/src/Monomer/Widgets/Containers/DropTarget.hs +++ b/src/Monomer/Widgets/Containers/DropTarget.hs @@ -12,20 +12,18 @@ without having to implement a custom widget. Usually works in tandem with Raises a user provided event when an item is dropped. The type must match with the dragged message, otherwise it will not be raised. - -Configs: - -- dropTargetStyle: The style to apply to the container when a dragged item is -on top. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Containers.DropTarget ( + -- * Configuration + DropTargetCfg, + dropTargetStyle, + -- * Constructors dropTarget, - dropTarget_, - dropTargetStyle + dropTarget_ ) where import Control.Lens ((&), (^.), (.~)) @@ -40,6 +38,12 @@ import Monomer.Widgets.Container import qualified Monomer.Lens as L +{-| +Configuration options for dropTarget: + +- 'dropTargetStyle': The style to apply to the container when a dragged item is + on top. +-} newtype DropTargetCfg = DropTargetCfg { _dtcDropStyle :: Maybe StyleState } diff --git a/src/Monomer/Widgets/Containers/Dropdown.hs b/src/Monomer/Widgets/Containers/Dropdown.hs index 8399ddb6..35c38cdf 100644 --- a/src/Monomer/Widgets/Containers/Dropdown.hs +++ b/src/Monomer/Widgets/Containers/Dropdown.hs @@ -7,23 +7,9 @@ Stability : experimental Portability : non-portable Dropdown widget, allowing selection of a single item from a collapsable list. -Both header and list content is customizable, plus its styling. In case only -text content is needed, 'Monomer.Widgets.Singles.TextDropdown' is easier to use. - -Configs: - -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetReqest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetReqest to generate when focus is lost. -- onChange: event to raise when selected item changes. -- onChangeReq: WidgetRequest to generate when selected item changes. -- onChangeIdx: event to raise when selected item changes. Includes index, -- onChangeIdxReq: WidgetRequest to generate when selected item changes. Includes -index. -- maxHeight: maximum height of the list when dropdown is expanded. -- itemBasicStyle: style of an item in the list when not selected. -- itemSelectedStyle: style of the selected item in the list. +Both header and list content is customizable, and so is its styling. In case +only 'Text' content is needed, 'Monomer.Widgets.Singles.TextDropdown' is easier +to use. -} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE ConstraintKinds #-} @@ -34,8 +20,10 @@ index. {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Containers.Dropdown ( + -- * Configuration DropdownCfg, - DropdownItem(..), + DropdownItem, + -- * Constructors dropdown, dropdown_, dropdownV, @@ -66,7 +54,22 @@ import qualified Monomer.Lens as L -- | Constraints for an item handled by dropdown. type DropdownItem a = SelectListItem a --- | Configuration options for dropdown widget. +{-| +Configuration options for dropdown: + +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when selected item changes. +- 'onChangeReq': 'WidgetRequest' to generate when selected item changes. +- 'onChangeIdx': event to raise when selected item changes. Includes index, +- 'onChangeIdxReq': 'WidgetRequest' to generate when selected item changes. + Includes index. +- 'maxHeight': maximum height of the list when dropdown is expanded. +- 'itemBasicStyle': 'Style' of an item in the list when not selected. +- 'itemSelectedStyle': 'Style' of the selected item in the list. +-} data DropdownCfg s e a = DropdownCfg { _ddcMaxHeight :: Maybe Double, _ddcItemStyle :: Maybe Style, @@ -190,7 +193,7 @@ dropdown_ field items makeMain makeRow configs = newNode where widgetData = WidgetLens field newNode = dropdownD_ widgetData items makeMain makeRow configs --- | Creates a dropdown using the given value and onChange event handler. +-- | Creates a dropdown using the given value and 'onChange' event handler. dropdownV :: (WidgetModel s, WidgetEvent e, Traversable t, DropdownItem a) => a -- ^ The current value. @@ -202,7 +205,7 @@ dropdownV dropdownV value handler items makeMain makeRow = newNode where newNode = dropdownV_ value handler items makeMain makeRow def --- | Creates a dropdown using the given value and onChange event handler. +-- | Creates a dropdown using the given value and 'onChange' event handler. -- | Accepts config. dropdownV_ :: (WidgetModel s, WidgetEvent e, Traversable t, DropdownItem a) @@ -220,7 +223,7 @@ dropdownV_ value handler items makeMain makeRow configs = newNode where -- | Creates a dropdown providing a WidgetData instance and config. dropdownD_ :: (WidgetModel s, WidgetEvent e, Traversable t, DropdownItem a) - => WidgetData s a -- ^ The WidgetData to retrieve the value from. + => WidgetData s a -- ^ The 'WidgetData' to retrieve the value from. -> t a -- ^ The list of selectable items. -> (a -> WidgetNode s e) -- ^ Function to create the header (always visible). -> (a -> WidgetNode s e) -- ^ Function to create the list (collapsable). diff --git a/src/Monomer/Widgets/Containers/Grid.hs b/src/Monomer/Widgets/Containers/Grid.hs index b6550ab2..93e969f6 100644 --- a/src/Monomer/Widgets/Containers/Grid.hs +++ b/src/Monomer/Widgets/Containers/Grid.hs @@ -9,14 +9,13 @@ Portability : non-portable Layout container which distributes size equally along the main axis. For hgrid it requests max width * elements as its width, and the max height as its height. The reverse happens for vgrid. - -Configs: - -- sizeReqUpdater: allows modifying the 'SizeReq' generated by the grid. -} {-# LANGUAGE FlexibleContexts #-} module Monomer.Widgets.Containers.Grid ( + -- * Configuration + GridCfg, + -- * Constructors hgrid, hgrid_, vgrid, @@ -36,6 +35,11 @@ import Monomer.Widgets.Container import qualified Monomer.Lens as L +{-| +Configuration options for grid: + +- 'sizeReqUpdater': allows modifying the 'SizeReq' generated by the grid. +-} newtype GridCfg = GridCfg { _grcSizeReqUpdater :: Maybe SizeReqUpdater } diff --git a/src/Monomer/Widgets/Containers/Keystroke.hs b/src/Monomer/Widgets/Containers/Keystroke.hs index 775eae70..2b82f248 100644 --- a/src/Monomer/Widgets/Containers/Keystroke.hs +++ b/src/Monomer/Widgets/Containers/Keystroke.hs @@ -6,12 +6,12 @@ Maintainer : fjvallarino@gmail.com Stability : experimental Portability : non-portable -Container which generates user provided events when combinations of keys happen. -Using this event makes sense at the application level or Composite level. If +Container which generates user provided events when combinations of keys occur. +Using these event makes sense at the application or Composite level. If you are implementing a widget from scratch, keyboard events are directly available. -The shortcut definitions are provided as a list of tuples of text, containing -the key combination, and associated event. The widget handles unordered +The shortcut definitions are provided as a list of tuples of 'Text', containing +the key combination and associated event. The widget handles unordered combinations of multiple keys at the same time, but does not support ordered sequences (pressing "a", releasing, then "b" and "c"). The available keys are: @@ -26,11 +26,6 @@ These can be combined, for example: - Copy: "Ctrl-c" or "C-c" - App config: "Ctrl-Shift-p" or "C-S-p" - -Configs: - -- ignoreChildrenEvts: If True, when a shortcut is detected, the KeyAction event -will not be passed down to children. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} @@ -39,6 +34,9 @@ will not be passed down to children. {-# LANGUAGE TemplateHaskell #-} module Monomer.Widgets.Containers.Keystroke ( + -- * Configuration + KeystrokeCfg, + -- * Constructors keystroke, keystroke_ ) where @@ -63,6 +61,12 @@ import Monomer.Widgets.Container import qualified Monomer.Lens as L +{-| +Configuration options for keystroke: + +- 'ignoreChildrenEvts': If True, when a shortcut is detected, the KeyAction + event will not be passed down to children. +-} newtype KeystrokeCfg = KeystrokeCfg { _kscIgnoreChildren :: Maybe Bool } diff --git a/src/Monomer/Widgets/Containers/Scroll.hs b/src/Monomer/Widgets/Containers/Scroll.hs index a1f983ea..2ab69fad 100644 --- a/src/Monomer/Widgets/Containers/Scroll.hs +++ b/src/Monomer/Widgets/Containers/Scroll.hs @@ -11,26 +11,10 @@ but limits itself to what its parent assigns. It allows navigating the content of the inner node with the scroll bars. It also supports automatic focus following. -Configs: - -- wheelRate: rate at which wheel movement causes scrolling. -- barColor: the color of the bar (container of the thumb). -- barHoverColor: the color of the bar when mouse is on top. -- barWidth: the width of the bar. -- thumbColor: the color of the thumb. -- thumbHoverColor: the color of the thumb when mouse is on top. -- thumbWidth: the width of the thumb. -- thumbRadius: the radius of the corners of the thumb. -- scrollOverlay_: whether scroll bar should be on top of content or by the side. -- scrollInvisible_: shortcut for setting invisible style. Useful with scroll -overlay, since it allows scrolling without taking up space or hiding content. -- scrollFollowFocus_: whether to auto scroll when focusing a non visible item. -- scrollStyle: the base style of the scroll bar. - Messages: -- ScrollTo: Causes the scroll to update its handles to ensure rect is visible. -- ScrollReset: Sets both handle positions to zero. +- 'ScrollTo': Causes the scroll to update its handles to ensure rect is visible. +- 'ScrollReset': Sets both handle positions to zero. -} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} @@ -41,13 +25,9 @@ Messages: {-# LANGUAGE TypeSynonymInstances #-} module Monomer.Widgets.Containers.Scroll ( + -- * Configuration + ScrollCfg, ScrollMessage(..), - scroll, - scroll_, - hscroll, - hscroll_, - vscroll, - vscroll_, scrollOverlay, scrollOverlay_, scrollFwdStyle, @@ -56,7 +36,14 @@ module Monomer.Widgets.Containers.Scroll ( scrollInvisible_, scrollFollowFocus, scrollFollowFocus_, - scrollStyle + scrollStyle, + -- * Constructors + scroll, + scroll_, + hscroll, + hscroll_, + vscroll, + vscroll_ ) where import Control.Applicative ((<|>)) @@ -85,6 +72,24 @@ data ActiveBar | VBar deriving (Eq, Show, Generic) +{-| +Configuration options for scroll: + +- 'wheelRate': rate at which wheel movement causes scrolling. +- 'barColor': the color of the bar (container of the thumb). +- 'barHoverColor': the color of the bar when mouse is on top. +- 'barWidth': the width of the bar. +- 'thumbColor': the color of the thumb. +- 'thumbHoverColor': the color of the thumb when mouse is on top. +- 'thumbWidth': the width of the thumb. +- 'thumbRadius': the radius of the corners of the thumb. +- 'scrollOverlay': whether scroll bar should be on top of content or by the + side. +- 'scrollInvisible': shortcut for setting invisible style. Useful with scroll + overlay, since it allows scrolling without taking up space or hiding content. +- 'scrollFollowFocus': whether to auto scroll when focusing a non visible item. +- 'scrollStyle': the base style of the scroll bar. +-} data ScrollCfg s e = ScrollCfg { _scScrollType :: Maybe ScrollType, _scScrollOverlay :: Maybe Bool, diff --git a/src/Monomer/Widgets/Containers/SelectList.hs b/src/Monomer/Widgets/Containers/SelectList.hs index b59a172c..68967104 100644 --- a/src/Monomer/Widgets/Containers/SelectList.hs +++ b/src/Monomer/Widgets/Containers/SelectList.hs @@ -8,24 +8,6 @@ Portability : non-portable Select list widget, allowing selection of a single item. List content (rows) is customizable, plus its styling. - -Configs: - -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetReqest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetReqest to generate when focus is lost. -- onChange: event to raise when selected item changes. -- onChangeReq: WidgetRequest to generate when selected item changes. -- onChangeIdx: event to raise when selected item changes. Includes index, -- onChangeIdxReq: WidgetRequest to generate when selected item changes. Includes -index. -- selectOnBlur: whether to select the currently highlighted item when navigating -away from the widget with tab key. -- itemBasicStyle: style of an item in the list when not selected. -- itemSelectedStyle: style of the selected item in the list. -- mergeRequired: whether merging children is required. Useful when select list -is part of another widget such as dropdown. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} @@ -34,9 +16,12 @@ is part of another widget such as dropdown. {-# LANGUAGE RecordWildCards #-} module Monomer.Widgets.Containers.SelectList ( + -- * Configuration SelectListCfg, - SelectListItem(..), + SelectListItem, SelectListMessage(..), + SelectListMakeRow, + -- * Constructors selectList, selectList_, selectListV, @@ -70,9 +55,27 @@ import qualified Monomer.Lens as L -- | Constraints for an item handled by selectList. type SelectListItem a = (Eq a, Show a, Typeable a) -- | Creates a row from an item. -type MakeRow s e a = a -> WidgetNode s e +type SelectListMakeRow s e a = a -> WidgetNode s e --- | Configuration options for selectList widget. +{-| +Configuration options for selectList: + +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when selected item changes. +- 'onChangeReq': 'WidgetRequest' to generate when selected item changes. +- 'onChangeIdx': event to raise when selected item changes. Includes index, +- 'onChangeIdxReq': 'WidgetRequest' to generate when selected item changes. + Includes index. +- 'selectOnBlur': whether to select the currently highlighted item when + navigating away from the widget with tab key. +- 'itemBasicStyle': style of an item in the list when not selected. +- 'itemSelectedStyle': style of the selected item in the list. +- 'mergeRequired': whether merging children is required. Useful when select list + is part of another widget such as dropdown. +-} data SelectListCfg s e a = SelectListCfg { _slcSelectOnBlur :: Maybe Bool, _slcItemStyle :: Maybe Style, @@ -188,7 +191,7 @@ selectList :: (WidgetModel s, WidgetEvent e, Traversable t, SelectListItem a) => ALens' s a -- ^ The lens into the model. -> t a -- ^ The list of selectable items. - -> MakeRow s e a -- ^ Function to create the list items. + -> SelectListMakeRow s e a -- ^ Function to create the list items. -> WidgetNode s e -- ^ The created dropdown. selectList field items makeRow = selectList_ field items makeRow def @@ -197,31 +200,31 @@ selectList_ :: (WidgetModel s, WidgetEvent e, Traversable t, SelectListItem a) => ALens' s a -- ^ The lens into the model. -> t a -- ^ The list of selectable items. - -> MakeRow s e a -- ^ Function to create the list items. + -> SelectListMakeRow s e a -- ^ Function to create the list items. -> [SelectListCfg s e a] -- ^ The config options. -> WidgetNode s e -- ^ The created dropdown. selectList_ field items makeRow configs = newNode where newNode = selectListD_ (WidgetLens field) items makeRow configs --- | Creates a select list using the given value and onChange event handler. +-- | Creates a select list using the given value and 'onChange' event handler. selectListV :: (WidgetModel s, WidgetEvent e, Traversable t, SelectListItem a) => a -- ^ The event to raise on change. -> (Int -> a -> e) -- ^ The list of selectable items. -> t a -- ^ The list of selectable items. - -> MakeRow s e a -- ^ Function to create the list items. + -> SelectListMakeRow s e a -- ^ Function to create the list items. -> WidgetNode s e -- ^ The created dropdown. selectListV value handler items makeRow = newNode where newNode = selectListV_ value handler items makeRow def --- | Creates a select list using the given value and onChange event handler. +-- | Creates a select list using the given value and 'onChange' event handler. -- Accepts config. selectListV_ :: (WidgetModel s, WidgetEvent e, Traversable t, SelectListItem a) => a -- ^ The event to raise on change. -> (Int -> a -> e) -- ^ The list of selectable items. -> t a -- ^ The list of selectable items. - -> MakeRow s e a -- ^ Function to create the list items. + -> SelectListMakeRow s e a -- ^ Function to create the list items. -> [SelectListCfg s e a] -- ^ The config options. -> WidgetNode s e -- ^ The created dropdown. selectListV_ value handler items makeRow configs = newNode where @@ -229,12 +232,12 @@ selectListV_ value handler items makeRow configs = newNode where newConfigs = onChangeIdx handler : configs newNode = selectListD_ widgetData items makeRow newConfigs --- | Creates a dropdown providing a WidgetData instance and config. +-- | Creates a dropdown providing a 'WidgetData' instance and config. selectListD_ :: (WidgetModel s, WidgetEvent e, Traversable t, SelectListItem a) - => WidgetData s a -- ^ The WidgetData to retrieve the value from. + => WidgetData s a -- ^ The 'WidgetData' to retrieve the value from. -> t a -- ^ The list of selectable items. - -> MakeRow s e a -- ^ Function to create the list items. + -> SelectListMakeRow s e a -- ^ Function to create the list items. -> [SelectListCfg s e a] -- ^ The config options. -> WidgetNode s e -- ^ The created dropdown. selectListD_ widgetData items makeRow configs = makeNode widget where @@ -252,7 +255,7 @@ makeSelectList :: (WidgetModel s, WidgetEvent e, SelectListItem a) => WidgetData s a -> Seq a - -> MakeRow s e a + -> SelectListMakeRow s e a -> SelectListCfg s e a -> SelectListState a -> Widget s e @@ -510,7 +513,7 @@ makeItemsList :: (WidgetModel s, WidgetEvent e, Eq a) => WidgetEnv s e -> Seq a - -> MakeRow s e a + -> SelectListMakeRow s e a -> SelectListCfg s e a -> WidgetId -> a diff --git a/src/Monomer/Widgets/Containers/Split.hs b/src/Monomer/Widgets/Containers/Split.hs index c575041b..b865cbdb 100644 --- a/src/Monomer/Widgets/Containers/Split.hs +++ b/src/Monomer/Widgets/Containers/Split.hs @@ -9,16 +9,6 @@ Portability : non-portable Splits the assigned space into two parts, vertically or horizontally, which are assigned to its two child nodes. The space assigned depends on the style and size requirements of each child node. - -Configs: - -- splitHandlePos: lens to a model field which provides the handle position. -- splitHandlePosV: value which provides the handle position. -- splitHandleSize: width of the handle. -- splitIgnoreChildResize: whether to ignore changes in size to its children -(otherwise, the handle position may change because of this). -- onChange: raises an event when the handle is moved. -- onChangeReq: generates a WidgetReqest when the handle is moved. -} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} @@ -26,14 +16,17 @@ Configs: {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Containers.Split ( - hsplit, - hsplit_, - vsplit, - vsplit_, + -- * Configuration + SplitCfg, splitHandlePos, splitHandlePosV, splitHandleSize, - splitIgnoreChildResize + splitIgnoreChildResize, + -- * Constructors + hsplit, + hsplit_, + vsplit, + vsplit_ ) where import Control.Applicative ((<|>)) @@ -50,6 +43,17 @@ import Monomer.Widgets.Containers.Stack (assignStackAreas) import qualified Monomer.Lens as L +{-| +Configuration options for split: + +- 'splitHandlePos': lens to a model field which provides the handle position. +- 'splitHandlePosV': value which provides the handle position. +- 'splitHandleSize': width of the handle. +- 'splitIgnoreChildResize': whether to ignore changes in size to its children + (otherwise, the handle position may change because of this). +- 'onChange': raises an event when the handle is moved. +- 'onChangeReq': generates a WidgetReqest when the handle is moved. +-} data SplitCfg s e = SplitCfg { _spcHandlePos :: Maybe (WidgetData s Double), _spcHandleSize :: Maybe Double, diff --git a/src/Monomer/Widgets/Containers/Stack.hs b/src/Monomer/Widgets/Containers/Stack.hs index 375d1ce6..55c04cf7 100644 --- a/src/Monomer/Widgets/Containers/Stack.hs +++ b/src/Monomer/Widgets/Containers/Stack.hs @@ -7,22 +7,19 @@ Stability : experimental Portability : non-portable Container which stacks its children along a main axis. The layout algorithm -considers the different type of size requirements and assigns the space -according to the logic defined in 'SizeReq'. If the requested fixed space is -larger that the viewport of the stack, the content will overflow. - -Configs: - -- ignoreEmptyArea: when the widgets do not use all the available space, -ignoring the unassigned space allows for mouse events to pass through. This is -useful in zstack layers. -- sizeReqUpdater: allows modifying the 'SizeReq' generated by the stack. +considers the different type of size requirements and assigns space according to +the logic defined in 'SizeReq'. If the requested fixed space is larger that the +viewport of the stack, the content will overflow. -} module Monomer.Widgets.Containers.Stack ( + -- * Configuration + StackCfg, + -- * Constructors hstack, hstack_, vstack, vstack_, + -- * Helpers assignStackAreas ) where @@ -40,6 +37,14 @@ import Monomer.Widgets.Container import qualified Monomer.Lens as L +{-| +Configuration options for stack: + +- 'ignoreEmptyArea': when the widgets do not use all the available space, + ignoring the unassigned space allows for mouse events to pass through. This is + useful in zstack layers. +- 'sizeReqUpdater': allows modifying the 'SizeReq' generated by the stack. +-} data StackCfg = StackCfg { _stcIgnoreEmptyArea :: Maybe Bool, _stcSizeReqUpdater :: Maybe SizeReqUpdater diff --git a/src/Monomer/Widgets/Containers/ThemeSwitch.hs b/src/Monomer/Widgets/Containers/ThemeSwitch.hs index d06decf6..c98eccd9 100644 --- a/src/Monomer/Widgets/Containers/ThemeSwitch.hs +++ b/src/Monomer/Widgets/Containers/ThemeSwitch.hs @@ -9,19 +9,17 @@ Portability : non-portable Switches to the provided theme for its child nodes. Note: this widget ignores style settings. If you need to display borders or any -other kind of style config, set it on the child node or wrap the themeSwitch -widget in a `Monomer.Widgets.Containers.Box`. - -Configs: - -- themeClearBg: indicates the clear color of the theme should be applied before -rendering children. Defaults to False. +other kind of style configuration, set it on the child node or wrap the +themeSwitch widget in a "Monomer.Widgets.Containers.Box". -} {-# LANGUAGE FlexibleContexts #-} module Monomer.Widgets.Containers.ThemeSwitch ( + -- * Configuration + ThemeSwitchCfg, themeClearBg, themeClearBg_, + -- * Constructors themeSwitch, themeSwitch_ ) where @@ -38,6 +36,12 @@ import Monomer.Widgets.Container import qualified Monomer.Lens as L +{-| +Configuration options for themeSwitch: + +- 'themeClearBg': indicates the clear color of the theme should be applied + before rendering children. Defaults to False. +-} newtype ThemeSwitchCfg = ThemeSwitchCfg { _tmcClearBg :: Maybe Bool } deriving (Eq, Show) diff --git a/src/Monomer/Widgets/Containers/Tooltip.hs b/src/Monomer/Widgets/Containers/Tooltip.hs index b09c3970..6be440a9 100644 --- a/src/Monomer/Widgets/Containers/Tooltip.hs +++ b/src/Monomer/Widgets/Containers/Tooltip.hs @@ -13,22 +13,18 @@ Tooltip styling is a bit unusual, since it only applies to the overlaid element. This means, padding will not be shown for the contained child element, but only on the message when the tooltip is active. If you need padding around the child element, you may want to use a box. - -Config: - -- width: the maximum width of the tooltip. Used for multiline. -- height: the maximum height of the tooltip. Used for multiline. -- tooltipDelay: the delay in ms before the tooltip is displayed. -- tooltipFollow: if, after tooltip is displayed, it should follow the mouse. -} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} module Monomer.Widgets.Containers.Tooltip ( - tooltip, - tooltip_, + -- * Configuration + TooltipCfg, tooltipDelay, - tooltipFollow + tooltipFollow, + -- * Constructors + tooltip, + tooltip_ ) where import Control.Applicative ((<|>)) @@ -45,6 +41,14 @@ import Monomer.Widgets.Container import qualified Monomer.Lens as L +{-| +Configuration options for tooltip: + +- 'width': the maximum width of the tooltip. Used for multiline. +- 'height': the maximum height of the tooltip. Used for multiline. +- 'tooltipDelay': the delay in ms before the tooltip is displayed. +- 'tooltipFollow': if, after tooltip is displayed, it should follow the mouse. +-} data TooltipCfg = TooltipCfg { _ttcDelay :: Maybe Int, _ttcFollowCursor :: Maybe Bool, diff --git a/src/Monomer/Widgets/Containers/ZStack.hs b/src/Monomer/Widgets/Containers/ZStack.hs index 6716a035..b100b2fd 100644 --- a/src/Monomer/Widgets/Containers/ZStack.hs +++ b/src/Monomer/Widgets/Containers/ZStack.hs @@ -12,22 +12,20 @@ to overlay unrelated widgets (text on top of an image). The order of the widgets is from bottom to top. -The container will request the largest horizontal and vertical size from its -child nodes. - -Config: - -- onlyTopActive: whether the top visible node is the only node that may receive -events. +The container will request the largest combination of horizontal and vertical +size requested by its child nodes. -} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} module Monomer.Widgets.Containers.ZStack ( + -- * Configuration + ZStackCfg, + onlyTopActive, + -- * Constructors zstack, - zstack_, - onlyTopActive + zstack_ ) where import Control.Applicative ((<|>)) @@ -46,6 +44,12 @@ import Monomer.Widgets.Container import qualified Monomer.Lens as L +{-| +Configuration options for zstack: + +- 'onlyTopActive': whether the top visible node is the only node that may + receive events. +-} newtype ZStackCfg = ZStackCfg { _zscOnlyTopActive :: Maybe Bool } diff --git a/src/Monomer/Widgets/Single.hs b/src/Monomer/Widgets/Single.hs index becdb3d0..0aef63a8 100644 --- a/src/Monomer/Widgets/Single.hs +++ b/src/Monomer/Widgets/Single.hs @@ -6,18 +6,20 @@ Maintainer : fjvallarino@gmail.com Stability : experimental Portability : non-portable -Helper for creating widgets without children elements +Helper for creating widgets without children elements. -} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE RankNTypes #-} module Monomer.Widgets.Single ( + -- * Re-exported modules module Monomer.Core, module Monomer.Core.Combinators, module Monomer.Event, module Monomer.Graphics, module Monomer.Widgets.Util, + -- * Configuration SingleGetBaseStyle, SingleGetCurrentStyle, SingleInitHandler, @@ -30,8 +32,9 @@ module Monomer.Widgets.Single ( SingleGetSizeReqHandler, SingleResizeHandler, SingleRenderHandler, - Single(..), + + -- * Constructors createSingle ) where diff --git a/src/Monomer/Widgets/Singles/Base/InputField.hs b/src/Monomer/Widgets/Singles/Base/InputField.hs index f58670fb..c117e9ca 100644 --- a/src/Monomer/Widgets/Singles/Base/InputField.hs +++ b/src/Monomer/Widgets/Singles/Base/InputField.hs @@ -10,8 +10,8 @@ Base single line text editing field. Extensible for handling specific textual representations of other types, such as numbers and dates. It is not meant for direct use, but to create custom widgets using it. -See 'Monomer.Widgets.Singles.NumericField', 'Monomer.Widgets.Singles.DateField' -and 'Monomer.Widgets.Singles.TimeField'. +See "Monomer.Widgets.Singles.NumericField", "Monomer.Widgets.Singles.DateField" +and "Monomer.Widgets.Singles.TimeField". -} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE ConstraintKinds #-} @@ -20,8 +20,14 @@ and 'Monomer.Widgets.Singles.TimeField'. {-# LANGUAGE RankNTypes #-} module Monomer.Widgets.Singles.Base.InputField ( + -- * Configuration + InputFieldValue, + InputWheelHandler, + InputDragHandler, InputFieldCfg(..), InputFieldState(..), + HistoryStep, + -- * Constructors inputField_ ) where @@ -121,14 +127,15 @@ data InputFieldCfg s e a = InputFieldCfg { _ifcDragHandler :: Maybe (InputDragHandler a), -- | Cursor to display on drag events. _ifcDragCursor :: Maybe CursorIcon, - -- | WidgetRequest to generate when focus is received. + -- | 'WidgetRequest' to generate when focus is received. _ifcOnFocusReq :: [Path -> WidgetRequest s e], - -- | WidgetRequest to generate when focus is lost. + -- | 'WidgetRequest' to generate when focus is lost. _ifcOnBlurReq :: [Path -> WidgetRequest s e], - -- | WidgetRequest to generate when value changes. + -- | 'WidgetRequest' to generate when value changes. _ifcOnChangeReq :: [a -> WidgetRequest s e] } +-- | Snapshot of a point in history of the input. data HistoryStep a = HistoryStep { _ihsValue :: a, _ihsText :: !Text, diff --git a/src/Monomer/Widgets/Singles/Button.hs b/src/Monomer/Widgets/Singles/Button.hs index b4225e7b..ae325751 100644 --- a/src/Monomer/Widgets/Singles/Button.hs +++ b/src/Monomer/Widgets/Singles/Button.hs @@ -7,29 +7,16 @@ Stability : experimental Portability : non-portable Button widget, with support for multiline text. At the most basic level, a -button consists of a caption and an event to raised when clicked. - -Configs: - -- trimSpaces: whether to remove leading/trailing spaces in the caption. -- ellipsis: if ellipsis should be used for overflown text. -- multiline: if text may be split in multiple lines. -- maxLines: maximum number of text lines to show. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onClick: event to raise when button is clicked. -- onClickReq: WidgetRequest to generate when button is clicked. -- resizeFactor: flexibility to have more or less spaced assigned. -- resizeFactorW: flexibility to have more or less horizontal spaced assigned. -- resizeFactorH: flexibility to have more or less vertical spaced assigned. +button consists of a caption and an event to raise when clicked. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.Button ( + -- * Configuration + ButtonCfg, + -- * Constructors button, button_, mainButton, @@ -54,6 +41,23 @@ data ButtonType | ButtonMain deriving (Eq, Show) +{-| +Configuration options for button: + +- 'trimSpaces': whether to remove leading/trailing spaces in the caption. +- 'ellipsis': if ellipsis should be used for overflown text. +- 'multiline': if text may be split in multiple lines. +- 'maxLines': maximum number of text lines to show. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onClick': event to raise when button is clicked. +- 'onClickReq': 'WidgetRequest' to generate when button is clicked. +- 'resizeFactor': flexibility to have more or less spaced assigned. +- 'resizeFactorW': flexibility to have more or less horizontal spaced assigned. +- 'resizeFactorH': flexibility to have more or less vertical spaced assigned. +-} data ButtonCfg s e = ButtonCfg { _btnButtonType :: Maybe ButtonType, _btnIgnoreTheme :: Maybe Bool, @@ -214,10 +218,9 @@ makeButton caption config = widget where createChildNode wenv node = newNode where nodeStyle = node ^. L.info . L.style - labelCfg = (_btnLabelCfg config) { - _lscCurrentStyle = Just childOfFocusedStyle - } - labelNode = label_ caption [ignoreTheme, labelCfg] + labelCfg = _btnLabelCfg config + labelCurrStyle = labelCurrentStyle childOfFocusedStyle + labelNode = label_ caption [ignoreTheme, labelCfg, labelCurrStyle] & L.info . L.style .~ nodeStyle newNode = node & L.children .~ Seq.singleton labelNode diff --git a/src/Monomer/Widgets/Singles/Checkbox.hs b/src/Monomer/Widgets/Singles/Checkbox.hs index 6e07d22d..6da763f2 100644 --- a/src/Monomer/Widgets/Singles/Checkbox.hs +++ b/src/Monomer/Widgets/Singles/Checkbox.hs @@ -8,27 +8,18 @@ Portability : non-portable Checkbox widget, used for interacting with boolean values. It does not include text, which can be added with a label in the desired position (usually with -hstack). Alternatively, `LabeledCheckbox` provides this functionality out of the -box. - -Configs: - -- checkboxMark: the type of checkbox mark. -- width: sets the max width/height of the checkbox. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes/is clicked. -- onChangeReq: WidgetRequest to generate when the value changes/is clicked. +hstack). Alternatively, "Monomer.Widgets.Singles.LabeledCheckbox" provides this +functionality out of the box. -} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.Checkbox ( + -- * Configuration + CheckboxCfg, CmbCheckboxMark(..), - CheckboxCfg(..), CheckboxMark(..), + -- * Constructors checkbox, checkbox_, checkboxV, @@ -60,7 +51,20 @@ class CmbCheckboxMark t where checkboxSquare :: t checkboxTimes :: t --- | Configuration options for checkbox widget. +{-| +Configuration options for checkbox: + +- 'checkboxMark': the type of checkbox mark. +- 'checkboxSquare': square checkbox mark. +- 'checkboxTimes': times/x checkbox mark. +- 'width': sets the max width/height of the checkbox. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes/is clicked. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes/is clicked. +-} data CheckboxCfg s e = CheckboxCfg { _ckcMark :: Maybe CheckboxMark, _ckcWidth :: Maybe Double, @@ -141,12 +145,12 @@ checkbox_ :: WidgetEvent e => ALens' s Bool -> [CheckboxCfg s e] -> WidgetNode s e checkbox_ field config = checkboxD_ (WidgetLens field) config --- | Creates a checkbox using the given value and onChange event handler. +-- | Creates a checkbox using the given value and 'onChange' event handler. checkboxV :: WidgetEvent e => Bool -> (Bool -> e) -> WidgetNode s e checkboxV value handler = checkboxV_ value handler def {-| -Creates a checkbox using the given value and onChange event handler. Accepts +Creates a checkbox using the given value and 'onChange' event handler. Accepts config. -} checkboxV_ @@ -154,7 +158,7 @@ checkboxV_ checkboxV_ value handler config = checkboxD_ (WidgetValue value) newConfig where newConfig = onChange handler : config --- | Creates a checkbox providing a WidgetData instance and config. +-- | Creates a checkbox providing a 'WidgetData' instance and config. checkboxD_ :: WidgetEvent e => WidgetData s Bool -> [CheckboxCfg s e] -> WidgetNode s e checkboxD_ widgetData configs = checkboxNode where diff --git a/src/Monomer/Widgets/Singles/ColorPicker.hs b/src/Monomer/Widgets/Singles/ColorPicker.hs index 54de9672..5c4f56ab 100644 --- a/src/Monomer/Widgets/Singles/ColorPicker.hs +++ b/src/Monomer/Widgets/Singles/ColorPicker.hs @@ -7,16 +7,6 @@ Stability : experimental Portability : non-portable Color picker using sliders and numeric fields. - -Configs: - -- showAlpha: whether to allow modifying the alpha channel or not. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when any of the values changes. -- onChangeReq: WidgetRequest to generate when any of the values changes. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} @@ -24,6 +14,9 @@ Configs: {-# LANGUAGE TemplateHaskell #-} module Monomer.Widgets.Singles.ColorPicker ( + -- * Configuration + ColorPickerCfg, + -- * Constructors colorPicker, colorPicker_, colorPickerV, @@ -57,6 +50,17 @@ import Monomer.Widgets.Singles.Spacer import qualified Monomer.Lens as L +{-| +Configuration options for colorPicker: + +- 'showAlpha': whether to allow modifying the alpha channel or not. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when any of the values changes. +- 'onChangeReq': 'WidgetRequest' to generate when any of the values changes. +-} data ColorPickerCfg s e = ColorPickerCfg { _cpcShowAlpha :: Maybe Bool, _cpcOnFocusReq :: [Path -> WidgetRequest s e], @@ -127,49 +131,49 @@ data ColorPickerEvt -- | Creates a color picker using the given lens. colorPicker - :: (WidgetModel sp, WidgetEvent ep) - => ALens' sp Color - -> WidgetNode sp ep + :: (WidgetModel s, WidgetEvent e) + => ALens' s Color + -> WidgetNode s e colorPicker field = colorPicker_ field def -- | Creates a color picker using the given lens. Accepts config. colorPicker_ - :: (WidgetModel sp, WidgetEvent ep) - => ALens' sp Color - -> [ColorPickerCfg sp ep] - -> WidgetNode sp ep + :: (WidgetModel s, WidgetEvent e) + => ALens' s Color + -> [ColorPickerCfg s e] + -> WidgetNode s e colorPicker_ field configs = colorPickerD_ wlens configs [] where wlens = WidgetLens field --- | Creates a color picker using the given value and onChange event handler. +-- | Creates a color picker using the given value and 'onChange' event handler. colorPickerV - :: (WidgetModel sp, WidgetEvent ep) + :: (WidgetModel s, WidgetEvent e) => Color - -> (Color -> ep) - -> WidgetNode sp ep + -> (Color -> e) + -> WidgetNode s e colorPickerV value handler = colorPickerV_ value handler def {-| -Creates a color picker using the given value and onChange event handler. Accepts -config. +Creates a color picker using the given value and 'onChange' event handler. +Accepts config. -} colorPickerV_ - :: (WidgetModel sp, WidgetEvent ep) + :: (WidgetModel s, WidgetEvent e) => Color - -> (Color -> ep) - -> [ColorPickerCfg sp ep] - -> WidgetNode sp ep + -> (Color -> e) + -> [ColorPickerCfg s e] + -> WidgetNode s e colorPickerV_ value handler configs = colorPickerD_ wdata newCfgs [] where wdata = WidgetValue value newCfgs = onChange handler : configs --- | Creates a color picker providing a WidgetData instance and config. +-- | Creates a color picker providing a 'WidgetData' instance and config. colorPickerD_ - :: (WidgetModel sp, WidgetEvent ep) - => WidgetData sp Color - -> [ColorPickerCfg sp ep] - -> [CompositeCfg Color ColorPickerEvt sp ep] - -> WidgetNode sp ep + :: (WidgetModel s, WidgetEvent e) + => WidgetData s Color + -> [ColorPickerCfg s e] + -> [CompositeCfg Color ColorPickerEvt s e] + -> WidgetNode s e colorPickerD_ wdata cfgs cmpCfgs = newNode where cfg = mconcat cfgs uiBuilder = buildUI cfg diff --git a/src/Monomer/Widgets/Singles/DateField.hs b/src/Monomer/Widgets/Singles/DateField.hs index 5a341bf6..eea98f17 100644 --- a/src/Monomer/Widgets/Singles/DateField.hs +++ b/src/Monomer/Widgets/Singles/DateField.hs @@ -15,27 +15,6 @@ is also supported. Supports different date formats and separators. Handles mouse wheel and shift + vertical drag to increase/decrease days. - -Configs: - -- validInput: field indicating if the current input is valid. Useful to show -warnings in the UI, or disable buttons if needed. -- resizeOnChange: Whether input causes ResizeWidgets requests. -- selectOnFocus: Whether all input should be selected when focus is received. -- minValue: Minimum valid date. -- maxValue: Maximum valid date. -- wheelRate: The rate at which wheel movement affects the date. -- dragRate: The rate at which drag movement affects the date. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes. -- onChangeReq: WidgetRequest to generate when the value changes. -- dateFormatDelimiter: which text delimiter to separate year, month and day. -- dateFormatDDMMYYYY: using the current delimiter, accept DD/MM/YYYY. -- dateFormatMMDDYYYY: using the current delimiter, accept MM/DD/YYYY. -- dateFormatYYYYMMDD: using the current delimiter, accept YYYY/MM/DD. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} @@ -45,7 +24,12 @@ warnings in the UI, or disable buttons if needed. {-# LANGUAGE UndecidableInstances #-} module Monomer.Widgets.Singles.DateField ( + -- * Configuration + DateFieldCfg, + FormattableDate, DayConverter(..), + DateTextConverter, + -- * Constructors dateField, dateField_, dateFieldV, @@ -101,6 +85,7 @@ instance DayConverter Day where convertFromDay = id convertToDay = Just +-- | Converts a 'Day' instance to and from 'Text'. class DateTextConverter a where dateAcceptText :: DateFormat -> Char -> Maybe a -> Maybe a -> Text -> (Bool, Bool, Maybe a) dateFromText :: DateFormat -> Char -> Text -> Maybe a @@ -138,9 +123,32 @@ instance (DayConverter a, DateTextConverter a) => DateTextConverter (Maybe a) wh dateToDay Nothing = Nothing dateToDay (Just value) = dateToDay value +-- | Constraints for date types accepted by dateField. type FormattableDate a = (Eq a, Ord a, Show a, DateTextConverter a, Typeable a) +{-| +Configuration options for dateField: + +- 'validInput': field indicating if the current input is valid. Useful to show + warnings in the UI, or disable buttons if needed. +- 'resizeOnChange': Whether input causes 'ResizeWidgets' requests. +- 'selectOnFocus': Whether all input should be selected when focus is received. +- 'minValue': Minimum valid date. +- 'maxValue': Maximum valid date. +- 'wheelRate': The rate at which wheel movement affects the date. +- 'dragRate': The rate at which drag movement affects the date. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes. +- 'dateFormatDelimiter': which text delimiter to separate year, month and day. +- 'dateFormatDDMMYYYY': using the current delimiter, accept DD/MM/YYYY. +- 'dateFormatMMDDYYYY': using the current delimiter, accept MM/DD/YYYY. +- 'dateFormatYYYYMMDD': using the current delimiter, accept YYYY/MM/DD. +-} data DateFieldCfg s e a = DateFieldCfg { _dfcCaretWidth :: Maybe Double, _dfcCaretMs :: Maybe Int, @@ -319,13 +327,13 @@ dateField_ dateField_ field configs = widget where widget = dateFieldD_ (WidgetLens field) configs --- | Creates a date field using the given value and onChange event handler. +-- | Creates a date field using the given value and 'onChange' event handler. dateFieldV :: (FormattableDate a, WidgetEvent e) => a -> (a -> e) -> WidgetNode s e dateFieldV value handler = dateFieldV_ value handler def --- | Creates a date field using the given value and onChange event handler. +-- | Creates a date field using the given value and 'onChange' event handler. -- Accepts config. dateFieldV_ :: (FormattableDate a, WidgetEvent e) @@ -338,7 +346,7 @@ dateFieldV_ value handler configs = newNode where newConfigs = onChange handler : configs newNode = dateFieldD_ widgetData newConfigs --- | Creates a date field providing a WidgetData instance and config. +-- | Creates a date field providing a 'WidgetData' instance and config. dateFieldD_ :: (FormattableDate a, WidgetEvent e) => WidgetData s a diff --git a/src/Monomer/Widgets/Singles/Dial.hs b/src/Monomer/Widgets/Singles/Dial.hs index 29f95282..66df6258 100644 --- a/src/Monomer/Widgets/Singles/Dial.hs +++ b/src/Monomer/Widgets/Singles/Dial.hs @@ -9,19 +9,7 @@ Portability : non-portable Dial widget, used for interacting with numeric values. It allows changing the value by keyboard arrows, dragging the mouse or using the wheel. -Similar in objective to Slider, but uses less space. - -Configs: - -- width: sets the max width/height of the dial. -- wheelRate: The rate at which wheel movement affects the number. -- dragRate: The rate at which drag movement affects the number. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes. -- onChangeReq: WidgetRequest to generate when the value changes. +Similar in objective to "Monomer.Widgets.Singles.Slider", but uses less space. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DeriveGeneric #-} @@ -31,6 +19,10 @@ Configs: {-# LANGUAGE ScopedTypeVariables #-} module Monomer.Widgets.Singles.Dial ( + -- * Configuration + DialValue, + DialCfg, + -- * Constructors dial, dial_, dialV, @@ -53,9 +45,22 @@ import Monomer.Widgets.Single import qualified Monomer.Lens as L +-- | Constraints for numeric types accepted by dial. type DialValue a = (Eq a, Show a, Real a, FromFractional a, Typeable a) --- | Configuration options for dial widget. +{-| +Configuration options for dial: + +- 'width': sets the max width/height of the dial. +- 'wheelRate': The rate at which wheel movement affects the number. +- 'dragRate': The rate at which drag movement affects the number. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes. +-} data DialCfg s e a = DialCfg { _dlcWidth :: Maybe Double, _dlcWheelRate :: Maybe Rational, @@ -161,7 +166,7 @@ dial_ dial_ field minVal maxVal cfgs = dialD_ (WidgetLens field) minVal maxVal cfgs {-| -Creates a dial using the given value and onChange event handler, providing +Creates a dial using the given value and 'onChange' event handler, providing minimum and maximum values. -} dialV @@ -174,7 +179,7 @@ dialV dialV value handler minVal maxVal = dialV_ value handler minVal maxVal def {-| -Creates a dial using the given value and onChange event handler, providing +Creates a dial using the given value and 'onChange' event handler, providing minimum and maximum values. Accepts config. -} @@ -192,7 +197,7 @@ dialV_ value handler minVal maxVal configs = newNode where newNode = dialD_ widgetData minVal maxVal newConfigs {-| -Creates a dial providing a WidgetData instance, minimum and maximum values and +Creates a dial providing a 'WidgetData' instance, minimum and maximum values and config. -} dialD_ diff --git a/src/Monomer/Widgets/Singles/ExternalLink.hs b/src/Monomer/Widgets/Singles/ExternalLink.hs index 15700f95..d3e402a5 100644 --- a/src/Monomer/Widgets/Singles/ExternalLink.hs +++ b/src/Monomer/Widgets/Singles/ExternalLink.hs @@ -8,28 +8,15 @@ Portability : non-portable Provides a clickable link that opens in the system's browser. It uses OS services to open the URI, which means not only URLs can be opened. - -Configs: - -- trimSpaces: whether to remove leading/trailing spaces in the caption. -- ellipsis: if ellipsis should be used for overflown text. -- multiline: if text may be split in multiple lines. -- maxLines: maximum number of text lines to show. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onClick: event to raise when button is clicked. -- onClickReq: WidgetRequest to generate when button is clicked. -- resizeFactor: flexibility to have more or less spaced assigned. -- resizeFactorW: flexibility to have more or less horizontal spaced assigned. -- resizeFactorH: flexibility to have more or less vertical spaced assigned. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.ExternalLink ( + -- * Configuration + ExternalLinkCfg, + -- * Constructors externalLink, externalLink_ ) where @@ -50,6 +37,23 @@ import Monomer.Widgets.Singles.Label import qualified Monomer.Lens as L +{-| +Configuration options for externalLink: + +- 'trimSpaces': whether to remove leading/trailing spaces in the caption. +- 'ellipsis': if ellipsis should be used for overflown text. +- 'multiline': if text may be split in multiple lines. +- 'maxLines': maximum number of text lines to show. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onClick': event to raise when button is clicked. +- 'onClickReq': 'WidgetRequest' to generate when button is clicked. +- 'resizeFactor': flexibility to have more or less spaced assigned. +- 'resizeFactorW': flexibility to have more or less horizontal spaced assigned. +- 'resizeFactorH': flexibility to have more or less vertical spaced assigned. +-} data ExternalLinkCfg s e = ExternalLinkCfg { _elcLabelCfg :: LabelCfg s e, _elcOnFocusReq :: [Path -> WidgetRequest s e], @@ -158,10 +162,9 @@ makeExternalLink caption url config = widget where createChildNode wenv node = newNode where nodeStyle = node ^. L.info . L.style - labelCfg = (_elcLabelCfg config) { - _lscCurrentStyle = Just childOfFocusedStyle - } - labelNode = label_ caption [ignoreTheme, labelCfg] + labelCfg = _elcLabelCfg config + labelCurrStyle = labelCurrentStyle childOfFocusedStyle + labelNode = label_ caption [ignoreTheme, labelCfg, labelCurrStyle] & L.info . L.style .~ nodeStyle childNode = labelNode newNode = node diff --git a/src/Monomer/Widgets/Singles/Icon.hs b/src/Monomer/Widgets/Singles/Icon.hs index e5d2a8d8..a7a77895 100644 --- a/src/Monomer/Widgets/Singles/Icon.hs +++ b/src/Monomer/Widgets/Singles/Icon.hs @@ -6,17 +6,16 @@ Maintainer : fjvallarino@gmail.com Stability : experimental Portability : non-portable -Icon widget. Used for showing some standard icos without the need of an asset. - -Configs: - -- width: the maximum width and height of the icon. +Icon widget. Used for showing basic icons without the need of an asset. -} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.Icon ( + -- * Configuration + IconCfg, IconType(..), + -- * Constructors icon, icon_ ) where @@ -41,7 +40,11 @@ data IconType | IconMinus deriving (Eq, Show) --- | Configuration options for icon widget. +{-| +Configuration options for icon: + +- 'width': the maximum width and height of the icon. +-} newtype IconCfg = IconCfg { _icWidth :: Maybe Double } diff --git a/src/Monomer/Widgets/Singles/Image.hs b/src/Monomer/Widgets/Singles/Image.hs index 1ac8ff70..14378149 100644 --- a/src/Monomer/Widgets/Singles/Image.hs +++ b/src/Monomer/Widgets/Singles/Image.hs @@ -12,26 +12,8 @@ Notes: - Depending on the type of image fit chosen and the assigned viewport, some space may remain unused. The alignment options exist to handle this situation. -- If you choose `fitNone`, `imageRepeatX` and `imageRepeatY` won't have any kind - of effect. - -Configs: - -- transparency: the alpha to apply when rendering the image. -- onLoadError: an event to report a load error. -- imageNearest: apply nearest filtering when stretching an image. -- imageRepeatX: repeat the image across the x coordinate. -- imageRepeatY: repeat the image across the y coordinate. -- fitNone: does not perform any streching if the size does not match viewport. -- fitFill: stretches the image to match the viewport. -- fitWidth: stretches the image to match the viewport width. Maintains ratio. -- fitHeight: stretches the image to match the viewport height. Maintains ratio. -- alignLeft: aligns left if extra space is available. -- alignRight: aligns right if extra space is available. -- alignCenter: aligns center if extra space is available. -- alignTop: aligns top if extra space is available. -- alignMiddle: aligns middle if extra space is available. -- alignBottom: aligns bottom if extra space is available. +- If you choose 'fitNone', adding 'imageRepeatX' and 'imageRepeatY' won't have + any kind of effect. -} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} @@ -39,7 +21,10 @@ Configs: {-# LANGUAGE ScopedTypeVariables #-} module Monomer.Widgets.Singles.Image ( + -- * Configuration + ImageCfg, ImageLoadError(..), + -- * Constructors image, image_, imageMem, @@ -89,7 +74,25 @@ data ImageLoadError | ImageInvalid String deriving (Eq, Show) --- | Configuration options for image widget. +{-| +Configuration options for image: + +- 'transparency': the alpha to apply when rendering the image. +- 'onLoadError': an event to report a load error. +- 'imageNearest': apply nearest filtering when stretching an image. +- 'imageRepeatX': repeat the image across the x coordinate. +- 'imageRepeatY': repeat the image across the y coordinate. +- 'fitNone': does not perform any streching if the size does not match viewport. +- 'fitFill': stretches the image to match the viewport. +- 'fitWidth': stretches the image to match the viewport width. Maintains ratio. +- 'fitHeight': stretches the image to match the viewport height. Maintains ratio. +- 'alignLeft': aligns left if extra space is available. +- 'alignRight': aligns right if extra space is available. +- 'alignCenter': aligns center if extra space is available. +- 'alignTop': aligns top if extra space is available. +- 'alignMiddle': aligns middle if extra space is available. +- 'alignBottom': aligns bottom if extra space is available. +-} data ImageCfg e = ImageCfg { _imcLoadError :: [ImageLoadError -> e], _imcFlags :: [ImageFlag], diff --git a/src/Monomer/Widgets/Singles/Label.hs b/src/Monomer/Widgets/Singles/Label.hs index 43ad74cc..08a47055 100644 --- a/src/Monomer/Widgets/Singles/Label.hs +++ b/src/Monomer/Widgets/Singles/Label.hs @@ -7,22 +7,14 @@ Stability : experimental Portability : non-portable Label widget, with support for multiline text. - -Configs: - -- trimSpaces: whether to remove leading/trailing spaces in the caption. -- ellipsis: if ellipsis should be used for overflown text. -- multiline: if text may be split in multiple lines. -- maxLines: maximum number of text lines to show. -- ignoreTheme: whether to load default style from theme or start empty. -- resizeFactor: flexibility to have more or less spaced assigned. -- resizeFactorW: flexibility to have more or less horizontal spaced assigned. -- resizeFactorH: flexibility to have more or less vertical spaced assigned. -} {-# LANGUAGE DeriveGeneric #-} module Monomer.Widgets.Singles.Label ( - LabelCfg(..), + -- * Configuration + LabelCfg, + -- * Constructors + labelCurrentStyle, label, label_, labelS, @@ -45,7 +37,18 @@ import Monomer.Widgets.Single import qualified Monomer.Lens as L --- | Configuration options for label widget. +{-| +Configuration options for label. + +- 'trimSpaces': whether to remove leading/trailing spaces in the caption. +- 'ellipsis': if ellipsis should be used for overflown text. +- 'multiline': if text may be split in multiple lines. +- 'maxLines': maximum number of text lines to show. +- 'ignoreTheme': whether to load default style from theme or start empty. +- 'resizeFactor': flexibility to have more or less spaced assigned. +- 'resizeFactorW': flexibility to have more or less horizontal spaced assigned. +- 'resizeFactorH': flexibility to have more or less vertical spaced assigned. +-} data LabelCfg s e = LabelCfg { _lscIgnoreTheme :: Maybe Bool, _lscTextTrim :: Maybe Bool, @@ -123,6 +126,16 @@ instance CmbResizeFactorDim (LabelCfg s e) where _lscFactorH = Just h } +-- | Custom current style to be used by the label widget. Useful for widgets +-- with an embedded label (for example, 'Monomer.Widgets.Singles.Button' and +-- 'Monomer.Widgets.Singles.ExternalLink'). +labelCurrentStyle + :: (WidgetEnv s e -> WidgetNode s e -> StyleState) + -> LabelCfg s e +labelCurrentStyle style = def { + _lscCurrentStyle = Just style +} + data LabelState = LabelState { _lstCaption :: Text, _lstTextStyle :: Maybe TextStyle, diff --git a/src/Monomer/Widgets/Singles/LabeledCheckbox.hs b/src/Monomer/Widgets/Singles/LabeledCheckbox.hs index 0e884615..75e912e5 100644 --- a/src/Monomer/Widgets/Singles/LabeledCheckbox.hs +++ b/src/Monomer/Widgets/Singles/LabeledCheckbox.hs @@ -8,36 +8,14 @@ Portability : non-portable Labeled checkbox, used for interacting with boolean values with an associated clickable label. - -Configs: - -- Text related - - textLeft: places the label to the left of the checkbox. - - textRight: places the label to the right of the checkbox. - - textTop: places the label to the top of the checkbox. - - textBottom: places the label to the bottom of the checkbox. - - trimSpaces: whether to remove leading/trailing spaces in the caption. - - ellipsis: if ellipsis should be used for overflown text. - - multiline: if text may be split in multiple lines. - - maxLines: maximum number of text lines to show. - - resizeFactor: flexibility to have more or less spaced assigned. - - resizeFactorW: flexibility to have more or less horizontal spaced assigned. - - resizeFactorH: flexibility to have more or less vertical spaced assigned. - -- Checkbox related - - checkboxMark: the type of checkbox mark. - - width: sets the max width/height of the checkbox. - - onFocus: event to raise when focus is received. - - onFocusReq: WidgetRequest to generate when focus is received. - - onBlur: event to raise when focus is lost. - - onBlurReq: WidgetRequest to generate when focus is lost. - - onChange: event to raise when the value changes/is clicked. - - onChangeReq: WidgetRequest to generate when the value changes/is clicked. -} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.LabeledCheckbox ( + -- * Configuration + LabeledCheckboxCfg, + -- * Constructors labeledCheckbox, labeledCheckbox_, labeledCheckboxV, @@ -61,6 +39,34 @@ import Monomer.Widgets.Singles.Label import qualified Monomer.Lens as L +{-| +Configuration options for labeledCheckbox: + +- Text related + + - 'textLeft': places the label to the left of the checkbox. + - 'textRight': places the label to the right of the checkbox. + - 'textTop': places the label to the top of the checkbox. + - 'textBottom': places the label to the bottom of the checkbox. + - 'trimSpaces': whether to remove leading/trailing spaces in the caption. + - 'ellipsis': if ellipsis should be used for overflown text. + - 'multiline': if text may be split in multiple lines. + - 'maxLines': maximum number of text lines to show. + - 'resizeFactor': flexibility to have more or less spaced assigned. + - 'resizeFactorW': flexibility for more or less horizontal spaced assigned. + - 'resizeFactorH': flexibility for more or less vertical spaced assigned. + +- Checkbox related + + - 'checkboxMark': the type of checkbox mark. + - 'width': sets the max width/height of the checkbox. + - 'onFocus': event to raise when focus is received. + - 'onFocusReq': 'WidgetRequest' to generate when focus is received. + - 'onBlur': event to raise when focus is lost. + - 'onBlurReq': 'WidgetRequest' to generate when focus is lost. + - 'onChange': event to raise when the value changes/is clicked. + - 'onChangeReq': 'WidgetRequest' to generate when the value changes/is clicked. +-} data LabeledCheckboxCfg s e = LabeledCheckboxCfg { _lchTextSide :: Maybe RectSide, _lchLabelCfg :: LabelCfg s e, @@ -197,7 +203,8 @@ labeledCheckbox_ labeledCheckbox_ caption field config = newNode where newNode = labeledCheckboxD_ caption (WidgetLens field) config --- | Creates a labeled checkbox using the given value and onChange event handler. +-- | Creates a labeled checkbox using the given value and 'onChange' event +-- handler. labeledCheckboxV :: WidgetEvent e => Text @@ -208,7 +215,7 @@ labeledCheckboxV caption value handler = newNode where newNode = labeledCheckboxV_ caption value handler def {-| -Creates a labeled checkbox using the given value and onChange event handler. +Creates a labeled checkbox using the given value and 'onChange' event handler. Accepts config. -} labeledCheckboxV_ @@ -222,7 +229,7 @@ labeledCheckboxV_ caption value handler config = newNode where newConfig = onChange handler : config newNode = labeledCheckboxD_ caption (WidgetValue value) newConfig --- | Creates a labeled checkbox providing a WidgetData instance and config. +-- | Creates a labeled checkbox providing a 'WidgetData' instance and config. labeledCheckboxD_ :: WidgetEvent e => Text diff --git a/src/Monomer/Widgets/Singles/LabeledRadio.hs b/src/Monomer/Widgets/Singles/LabeledRadio.hs index 0faff875..c719db5f 100644 --- a/src/Monomer/Widgets/Singles/LabeledRadio.hs +++ b/src/Monomer/Widgets/Singles/LabeledRadio.hs @@ -9,35 +9,14 @@ Portability : non-portable Radio widget, used for interacting with a fixed set of values with an associated clickable label. Each instance of the radio will be associated with a single value. - -Configs: - -- Text related - - textLeft: places the label to the left of the radio. - - textRight: places the label to the right of the radio. - - textTop: places the label to the top of the radio. - - textBottom: places the label to the bottom of the radio. - - trimSpaces: whether to remove leading/trailing spaces in the caption. - - ellipsis: if ellipsis should be used for overflown text. - - multiline: if text may be split in multiple lines. - - maxLines: maximum number of text lines to show. - - resizeFactor: flexibility to have more or less spaced assigned. - - resizeFactorW: flexibility to have more or less horizontal spaced assigned. - - resizeFactorH: flexibility to have more or less vertical spaced assigned. - -- Radio related - - width: sets the max width/height of the radio. - - onFocus: event to raise when focus is received. - - onFocusReq: WidgetRequest to generate when focus is received. - - onBlur: event to raise when focus is lost. - - onBlurReq: WidgetRequest to generate when focus is lost. - - onChange: event to raise when the value changes/is clicked. - - onChangeReq: WidgetRequest to generate when the value changes/is clicked. -} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.LabeledRadio ( + -- * Configuration + LabeledRadioCfg, + -- * Constructors labeledRadio, labeledRadio_, labeledRadioV, @@ -60,6 +39,34 @@ import Monomer.Widgets.Singles.Radio import qualified Monomer.Lens as L +{-| +Configuration options for labeledRadio: + +- Text related + + - 'textLeft': places the label to the left of the radio. + - 'textRight': places the label to the right of the radio. + - 'textTop': places the label to the top of the radio. + - 'textBottom': places the label to the bottom of the radio. + - 'trimSpaces': whether to remove leading/trailing spaces in the caption. + - 'ellipsis': if ellipsis should be used for overflown text. + - 'multiline': if text may be split in multiple lines. + - 'maxLines': maximum number of text lines to show. + - 'resizeFactor': flexibility to have more or less spaced assigned. + - 'resizeFactorW': flexibility for more or less horizontal spaced assigned. + - 'resizeFactorH': flexibility for more or less vertical spaced assigned. + +- Radio related + + - 'width': sets the max width/height of the radio. + - 'onFocus': event to raise when focus is received. + - 'onFocusReq': 'WidgetRequest' to generate when focus is received. + - 'onBlur': event to raise when focus is lost. + - 'onBlurReq': 'WidgetRequest' to generate when focus is lost. + - 'onChange': event to raise when the value changes/is clicked. + - 'onChangeReq': 'WidgetRequest' to generate when the value changes/is + clicked. +-} data LabeledRadioCfg s e a = LabeledRadioCfg { _lchTextSide :: Maybe RectSide, _lchLabelCfg :: LabelCfg s e, @@ -195,7 +202,7 @@ labeledRadio_ labeledRadio_ caption option field config = newNode where newNode = labeledRadioD_ caption option (WidgetLens field) config --- | Creates a labeled radio using the given value and onChange event handler. +-- | Creates a labeled radio using the given value and 'onChange' event handler. labeledRadioV :: (Eq a, WidgetEvent e) => Text @@ -207,7 +214,7 @@ labeledRadioV caption option value handler = newNode where newNode = labeledRadioV_ caption option value handler def {-| -Creates a labeled radio using the given value and onChange event handler. +Creates a labeled radio using the given value and 'onChange' event handler. Accepts config. -} labeledRadioV_ @@ -222,7 +229,7 @@ labeledRadioV_ caption option value handler config = newNode where newConfig = onChange handler : config newNode = labeledRadioD_ caption option (WidgetValue value) newConfig --- | Creates a labeled radio providing a WidgetData instance and config. +-- | Creates a labeled radio providing a 'WidgetData' instance and config. labeledRadioD_ :: (Eq a, WidgetEvent e) => Text diff --git a/src/Monomer/Widgets/Singles/NumericField.hs b/src/Monomer/Widgets/Singles/NumericField.hs index 2d22ddba..225eb7ad 100644 --- a/src/Monomer/Widgets/Singles/NumericField.hs +++ b/src/Monomer/Widgets/Singles/NumericField.hs @@ -12,25 +12,6 @@ Supports instances of the 'FromFractional' typeclass. Several basic types are implemented, both for integer and floating point types. Handles mouse wheel and shift + vertical drag to increase/decrease the number. - -Configs: - -- validInput: field indicating if the current input is valid. Useful to show -warnings in the UI, or disable buttons if needed. -- resizeOnChange: Whether input causes ResizeWidgets requests. -- selectOnFocus: Whether all input should be selected when focus is received. -- minValue: Minimum valid number. -- maxValue: Maximum valid number. -- wheelRate: The rate at which wheel movement affects the number. -- dragRate: The rate at which drag movement affects the number. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes. -- onChangeReq: WidgetRequest to generate when the value changes. -- decimals: the maximum number of digits after the decimal separator. Defaults -to zero for integers and two for floating point types. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleInstances #-} @@ -39,6 +20,11 @@ to zero for integers and two for floating point types. {-# LANGUAGE UndecidableInstances #-} module Monomer.Widgets.Singles.NumericField ( + -- * Configuration + NumericFieldCfg, + FormattableNumber, + NumericTextConverter, + -- * Constructors numericField, numericField_, numericFieldV, @@ -69,6 +55,7 @@ import Monomer.Widgets.Singles.Base.InputField import qualified Monomer.Lens as L import qualified Monomer.Widgets.Util.Parser as P +-- | Converts a numeric instance to and from 'Text'. class NumericTextConverter a where numericAcceptText :: Maybe a -> Maybe a -> Int -> Text -> (Bool, Bool, Maybe a) numericFromText :: Text -> Maybe a @@ -108,9 +95,30 @@ instance (FromFractional a, NumericTextConverter a) => NumericTextConverter (May numericToFractional (Just value) = numericToFractional value numericFromFractional = Just . numericFromFractional +-- | Constraints for numeric types accepted by numericField. type FormattableNumber a = (Eq a, Ord a, Show a, NumericTextConverter a, Typeable a) +{-| +Configuration options for numericField: + +- 'validInput': field indicating if the current input is valid. Useful to show + warnings in the UI, or disable buttons if needed. +- 'resizeOnChange': Whether input causes ResizeWidgets requests. +- 'selectOnFocus': Whether all input should be selected when focus is received. +- 'minValue': Minimum valid number. +- 'maxValue': Maximum valid number. +- 'wheelRate': The rate at which wheel movement affects the number. +- 'dragRate': The rate at which drag movement affects the number. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes. +- 'decimals': the maximum number of digits after the decimal separator. Defaults + to zero for integers and two for floating point types. +-} data NumericFieldCfg s e a = NumericFieldCfg { _nfcCaretWidth :: Maybe Double, _nfcCaretMs :: Maybe Int, @@ -267,13 +275,13 @@ numericField_ numericField_ field configs = widget where widget = numericFieldD_ (WidgetLens field) configs --- | Creates a numeric field using the given value and onChange event handler. +-- | Creates a numeric field using the given value and 'onChange' event handler. numericFieldV :: (FormattableNumber a, WidgetEvent e) => a -> (a -> e) -> WidgetNode s e numericFieldV value handler = numericFieldV_ value handler def --- | Creates a numeric field using the given value and onChange event handler. +-- | Creates a numeric field using the given value and 'onChange' event handler. -- Accepts config. numericFieldV_ :: (FormattableNumber a, WidgetEvent e) @@ -286,7 +294,7 @@ numericFieldV_ value handler configs = newNode where newConfigs = onChange handler : configs newNode = numericFieldD_ widgetData newConfigs --- | Creates a numeric field providing a WidgetData instance and config. +-- | Creates a numeric field providing a 'WidgetData' instance and config. numericFieldD_ :: forall s e a . (FormattableNumber a, WidgetEvent e) => WidgetData s a diff --git a/src/Monomer/Widgets/Singles/Radio.hs b/src/Monomer/Widgets/Singles/Radio.hs index a54671d8..ba4753d1 100644 --- a/src/Monomer/Widgets/Singles/Radio.hs +++ b/src/Monomer/Widgets/Singles/Radio.hs @@ -9,23 +9,16 @@ Portability : non-portable Radio widget, used for interacting with a fixed set of values. Each instance of the radio will be associated with a single value. It does not include text, which should be added as a label in the desired position (usually with hstack). -Alternatively, `LabeledRadio` provides this functionality out of the box. - -Configs: - -- width: sets the max width/height of the radio. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes/is clicked. -- onChangeReq: WidgetRequest to generate when the value changes/is clicked. +Alternatively, 'Monomer.Widgets.Singles.LabeledRadio' provides this +functionality out of the box. -} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.Radio ( - RadioCfg(..), + -- * Configuration + RadioCfg, + -- * Constructors radio, radio_, radioV, @@ -44,7 +37,17 @@ import Monomer.Widgets.Single import qualified Monomer.Lens as L --- | Configuration options for radio widget. +{-| +Configuration options for radio: + +- 'width': sets the max width/height of the radio. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes/is clicked. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes/is clicked. +-} data RadioCfg s e a = RadioCfg { _rdcWidth :: Maybe Double, _rdcOnFocusReq :: [Path -> WidgetRequest s e], @@ -119,11 +122,11 @@ radio_ -> WidgetNode s e radio_ option field configs = radioD_ option (WidgetLens field) configs --- | Creates a radio using the given value and onChange event handler. +-- | Creates a radio using the given value and 'onChange' event handler. radioV :: (Eq a, WidgetEvent e) => a -> a -> (a -> e) -> WidgetNode s e radioV option value handler = radioV_ option value handler def --- | Creates a radio using the given value and onChange event handler. +-- | Creates a radio using the given value and 'onChange' event handler. -- Accepts config. radioV_ :: (Eq a, WidgetEvent e) @@ -137,7 +140,7 @@ radioV_ option value handler configs = newNode where newConfigs = onChange handler : configs newNode = radioD_ option widgetData newConfigs --- | Creates a radio providing a WidgetData instance and config. +-- | Creates a radio providing a 'WidgetData' instance and config. radioD_ :: (Eq a, WidgetEvent e) => a diff --git a/src/Monomer/Widgets/Singles/SeparatorLine.hs b/src/Monomer/Widgets/Singles/SeparatorLine.hs index adeb718a..e433a764 100644 --- a/src/Monomer/Widgets/Singles/SeparatorLine.hs +++ b/src/Monomer/Widgets/Singles/SeparatorLine.hs @@ -13,15 +13,13 @@ and viceversa. The line has the provided width in the direction orthogonal to the layout direction, and takes all the available space in the other direction. In case of wanting a shorter line, padding should be used. - -Configs: - -- width: the max width of the line. -- resizeFactor: flexibility to have more or less spaced assigned. -} {-# LANGUAGE FlexibleContexts #-} module Monomer.Widgets.Singles.SeparatorLine ( + -- * Configuration + SeparatorLineCfg, + -- * Constructors separatorLine, separatorLine_ ) where @@ -36,7 +34,12 @@ import Monomer.Widgets.Single import qualified Monomer.Core.Lens as L --- | Configuration options for separatorLine widget. +{-| +Configuration options for separatorLine: + +- 'width': the max width of the line. +- 'resizeFactor': flexibility to have more or less spaced assigned. +-} data SeparatorLineCfg = SeparatorLineCfg { _slcWidth :: Maybe Double, _slcFactor :: Maybe Double diff --git a/src/Monomer/Widgets/Singles/Slider.hs b/src/Monomer/Widgets/Singles/Slider.hs index 7739267f..d62237fd 100644 --- a/src/Monomer/Widgets/Singles/Slider.hs +++ b/src/Monomer/Widgets/Singles/Slider.hs @@ -9,20 +9,8 @@ Portability : non-portable Slider widget, used for interacting with numeric values. It allows changing the value by keyboard arrows, dragging the mouse or using the wheel. -Similar in objective to Dial, but more convenient in some layouts. - -- width: sets the size of the secondary axis of the Slider. -- radius: the radius of the corners of the Slider. -- wheelRate: The rate at which wheel movement affects the number. -- dragRate: The rate at which drag movement affects the number. -- thumbVisible: whether a thumb should be visible or not. -- thumbFactor: the size of the thumb relative to width. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes. -- onChangeReq: WidgetRequest to generate when the value changes. +Similar in objective to 'Monomer.Widgets.Singles.Dial', but more convenient in +some layouts. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DeriveGeneric #-} @@ -32,6 +20,10 @@ Similar in objective to Dial, but more convenient in some layouts. {-# LANGUAGE ScopedTypeVariables #-} module Monomer.Widgets.Singles.Slider ( + -- * Configuration + SliderValue, + SliderCfg, + -- * Constructors hslider, hslider_, vslider, @@ -59,10 +51,25 @@ import Monomer.Widgets.Single import qualified Monomer.Lens as L --- | Constraints for the values handled by slider widget. +-- | Constraints for numeric types accepted by slider. type SliderValue a = (Eq a, Show a, Real a, FromFractional a, Typeable a) --- | Configuration options for slider widget. +{-| +Configuration options for slider: + +- 'width': sets the size of the secondary axis of the Slider. +- 'radius': the radius of the corners of the Slider. +- 'wheelRate': The rate at which wheel movement affects the number. +- 'dragRate': The rate at which drag movement affects the number. +- 'thumbVisible': whether a thumb should be visible or not. +- 'thumbFactor': the size of the thumb relative to width. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes. +-} data SliderCfg s e a = SliderCfg { _slcRadius :: Maybe Double, _slcWidth :: Maybe Double, @@ -223,7 +230,7 @@ vslider_ field minVal maxVal cfg = sliderD_ False wlens minVal maxVal cfg where wlens = WidgetLens field {-| -Creates a horizontal slider using the given value and onChange event handler, +Creates a horizontal slider using the given value and 'onChange' event handler, providing minimum and maximum values. -} hsliderV @@ -236,7 +243,7 @@ hsliderV hsliderV value handler minVal maxVal = hsliderV_ value handler minVal maxVal def {-| -Creates a horizontal slider using the given value and onChange event handler, +Creates a horizontal slider using the given value and 'onChange' event handler, providing minimum and maximum values. Accepts config. -} hsliderV_ @@ -253,7 +260,7 @@ hsliderV_ value handler minVal maxVal configs = newNode where newNode = sliderD_ True widgetData minVal maxVal newConfigs {-| -Creates a vertical slider using the given value and onChange event handler, +Creates a vertical slider using the given value and 'onChange' event handler, providing minimum and maximum values. -} vsliderV @@ -266,7 +273,7 @@ vsliderV vsliderV value handler minVal maxVal = vsliderV_ value handler minVal maxVal def {-| -Creates a vertical slider using the given value and onChange event handler, +Creates a vertical slider using the given value and 'onChange' event handler, providing minimum and maximum values. Accepts config. -} vsliderV_ @@ -283,8 +290,8 @@ vsliderV_ value handler minVal maxVal configs = newNode where newNode = sliderD_ False widgetData minVal maxVal newConfigs {-| -Creates a slider providing direction, a WidgetData instance, minimum and maximum -values and config. +Creates a slider providing direction, a 'WidgetData' instance, minimum and +maximum values and config. -} sliderD_ :: (SliderValue a, WidgetEvent e) diff --git a/src/Monomer/Widgets/Singles/Spacer.hs b/src/Monomer/Widgets/Singles/Spacer.hs index 17e913a6..8a620b9d 100644 --- a/src/Monomer/Widgets/Singles/Spacer.hs +++ b/src/Monomer/Widgets/Singles/Spacer.hs @@ -11,15 +11,13 @@ Filler is used for taking all the unused space between two widgets. Useful for alignment purposes. Both adapt to the current layout direction, if any. - -Configs: - -- width: the max width for spacer, the reference for filler. -- resizeFactor: flexibility to have more or less spaced assigned. -} {-# LANGUAGE FlexibleContexts #-} module Monomer.Widgets.Singles.Spacer ( + -- * Configuration + SpacerCfg, + -- * Constructors spacer, spacer_, filler, @@ -36,7 +34,12 @@ import Monomer.Widgets.Single import qualified Monomer.Core.Lens as L --- | Configuration options for spacer widget. +{-| +Configuration options for spacer widget: + +- 'width': the max width for spacer, the reference for filler. +- 'resizeFactor': flexibility to have more or less spaced assigned. +-} data SpacerCfg = SpacerCfg { _spcWidth :: Maybe Double, _spcFactor :: Maybe Double diff --git a/src/Monomer/Widgets/Singles/TextArea.hs b/src/Monomer/Widgets/Singles/TextArea.hs index c2d75efe..8814e928 100644 --- a/src/Monomer/Widgets/Singles/TextArea.hs +++ b/src/Monomer/Widgets/Singles/TextArea.hs @@ -6,21 +6,7 @@ Maintainer : fjvallarino@gmail.com Stability : experimental Portability : non-portable -Input field for multi line Text. - -Configs: - -- maxLength: the maximum length of input text. -- maxLines: the maximum number of lines of input text. -- acceptTab: whether to handle tab and convert it to spaces (cancelling change -of focus), or keep default behaviour and lose focus. -- selectOnFocus: Whether all input should be selected when focus is received. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes. -- onChangeReq: WidgetRequest to generate when the value changes. +Input field for multiline 'Text'. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DeriveGeneric #-} @@ -29,6 +15,9 @@ of focus), or keep default behaviour and lose focus. {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.TextArea ( + -- * Configuration + TextAreaCfg, + -- * Constructors textArea, textArea_, textAreaV, @@ -61,6 +50,21 @@ defCaretW = 2 defCaretMs :: Int defCaretMs = 500 +{-| +Configuration options for textArea: + +- 'maxLength': the maximum length of input text. +- 'maxLines': the maximum number of lines of input text. +- 'acceptTab': whether to handle tab and convert it to spaces (cancelling change + of focus), or keep default behaviour and lose focus. +- 'selectOnFocus': Whether all input should be selected when focus is received. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes. +-} data TextAreaCfg s e = TextAreaCfg { _tacCaretWidth :: Maybe Double, _tacCaretMs :: Maybe Int, @@ -203,11 +207,11 @@ textArea_ textArea_ field configs = textAreaD_ wdata configs where wdata = WidgetLens field --- | Creates a text area using the given value and onChange event handler. +-- | Creates a text area using the given value and 'onChange' event handler. textAreaV :: WidgetEvent e => Text -> (Text -> e) -> WidgetNode s e textAreaV value handler = textAreaV_ value handler def --- | Creates a text area using the given value and onChange event handler. +-- | Creates a text area using the given value and 'onChange' event handler. -- Accepts config. textAreaV_ :: WidgetEvent e => Text -> (Text -> e) -> [TextAreaCfg s e] -> WidgetNode s e @@ -215,7 +219,7 @@ textAreaV_ value handler configs = textAreaD_ wdata newConfig where wdata = WidgetValue value newConfig = onChange handler : configs --- | Creates a text area providing a WidgetData instance and config. +-- | Creates a text area providing a 'WidgetData' instance and config. textAreaD_ :: WidgetEvent e => WidgetData s Text diff --git a/src/Monomer/Widgets/Singles/TextDropdown.hs b/src/Monomer/Widgets/Singles/TextDropdown.hs index 1ac5fcb0..eb065cc0 100644 --- a/src/Monomer/Widgets/Singles/TextDropdown.hs +++ b/src/Monomer/Widgets/Singles/TextDropdown.hs @@ -9,25 +9,13 @@ Portability : non-portable Dropdown widget, allowing selection of a single item from a collapsable list. Both header and list content is text based. In case a customizable version is is needed, 'Monomer.Widgets.Containers.Dropdown' can be used. - -Configs: - -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetReqest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetReqest to generate when focus is lost. -- onChange: event to raise when selected item changes. -- onChangeReq: WidgetRequest to generate when selected item changes. -- onChangeIdx: event to raise when selected item changes. Includes index, -- onChangeIdxReq: WidgetRequest to generate when selected item changes. Includes -index. -- maxHeight: maximum height of the list when dropdown is expanded. -- itemBasicStyle: style of an item in the list when not selected. -- itemSelectedStyle: style of the selected item in the list. -} {-# LANGUAGE ConstraintKinds #-} module Monomer.Widgets.Singles.TextDropdown ( + -- * Configuratiom + TextDropdownItem, + -- * Constructors textDropdown, textDropdown_, textDropdownV, @@ -48,6 +36,7 @@ import Monomer.Core.Combinators import Monomer.Widgets.Containers.Dropdown import Monomer.Widgets.Singles.Label +-- | Constraints for an item handled by textDropdown. type TextDropdownItem a = DropdownItem a {-| @@ -77,8 +66,8 @@ textDropdown_ field items toText configs = newNode where newNode = textDropdownD_ (WidgetLens field) items toText configs {-| -Creates a text dropdown using the given value and onChange event handler. Takes -a function for converting the type to Text. +Creates a text dropdown using the given value and 'onChange' event handler. +Takes a function for converting the type to Text. -} textDropdownV :: (WidgetModel s, WidgetEvent e, Traversable t, TextDropdownItem a, TextShow a) @@ -90,8 +79,8 @@ textDropdownV value handler items = newNode where newNode = textDropdownV_ value handler items showt def {-| -Creates a text dropdown using the given value and onChange event handler. Takes -a function for converting the type to Text. Accepts config. +Creates a text dropdown using the given value and 'onChange' event handler. +Takes a function for converting the type to Text. Accepts config. -} textDropdownV_ :: (WidgetModel s, WidgetEvent e, Traversable t, TextDropdownItem a) @@ -107,7 +96,7 @@ textDropdownV_ value handler items toText configs = newNode where newNode = textDropdownD_ widgetData items toText newConfigs {-| -Creates a text dropdown providing a WidgetData instance and config. Takes +Creates a text dropdown providing a 'WidgetData' instance and config. Takes a function for converting the type to Text. -} textDropdownD_ @@ -148,7 +137,7 @@ textDropdownS_ field items configs = newNode where newNode = textDropdownDS_ (WidgetLens field) items configs {-| -Creates a text dropdown using the given value and onChange event handler. The +Creates a text dropdown using the given value and 'onChange' event handler. The type must be have a 'Show' instance. -} textDropdownSV @@ -161,7 +150,7 @@ textDropdownSV value handler items = newNode where newNode = textDropdownSV_ value handler items def {-| -Creates a text dropdown using the given value and onChange event handler. The +Creates a text dropdown using the given value and 'onChange' event handler. The type must be have a 'Show' instance. Accepts config. -} textDropdownSV_ @@ -177,7 +166,7 @@ textDropdownSV_ value handler items configs = newNode where newNode = textDropdownDS_ widgetData items newConfigs {-| -Creates a text dropdown providing a WidgetData instance and config. The +Creates a text dropdown providing a 'WidgetData' instance and config. The type must be have a 'Show' instance. -} textDropdownDS_ diff --git a/src/Monomer/Widgets/Singles/TextField.hs b/src/Monomer/Widgets/Singles/TextField.hs index 4ac08fa9..cd09ff46 100644 --- a/src/Monomer/Widgets/Singles/TextField.hs +++ b/src/Monomer/Widgets/Singles/TextField.hs @@ -6,23 +6,7 @@ Maintainer : fjvallarino@gmail.com Stability : experimental Portability : non-portable -Input field for single line Text. - -Configs: - -- validInput: field indicating if the current input is valid. Useful to show - warnings in the UI, or disable buttons if needed. -- resizeOnChange: Whether input causes ResizeWidgets requests. -- selectOnFocus: Whether all input should be selected when focus is received. -- maxLength: the maximum length of input text. -- textFieldDisplayChar: the character that will be displayed as replacement of the - real text. Useful for password fields. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes. -- onChangeReq: WidgetRequest to generate when the value changes. +Input field for single line 'Text'. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} @@ -30,7 +14,10 @@ Configs: {-# LANGUAGE MultiParamTypeClasses #-} module Monomer.Widgets.Singles.TextField ( + -- * Configuration + TextFieldCfg, textFieldDisplayChar, + -- * Constructors textField, textField_, textFieldV, @@ -52,6 +39,23 @@ import Monomer.Widgets.Singles.Base.InputField import qualified Monomer.Lens as L +{-| +Configuration options for textField: + +- 'validInput': field indicating if the current input is valid. Useful to show + warnings in the UI, or disable buttons if needed. +- 'resizeOnChange': Whether input causes ResizeWidgets requests. +- 'selectOnFocus': Whether all input should be selected when focus is received. +- 'maxLength': the maximum length of input text. +- 'textFieldDisplayChar': the character that will be displayed as replacement of + the real text. Useful for password fields. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes. +-} data TextFieldCfg s e = TextFieldCfg { _tfcCaretWidth :: Maybe Double, _tfcCaretMs :: Maybe Int, @@ -187,11 +191,11 @@ textField_ :: WidgetEvent e => ALens' s Text -> [TextFieldCfg s e] -> WidgetNode s e textField_ field configs = textFieldD_ (WidgetLens field) configs --- | Creates a text field using the given value and onChange event handler. +-- | Creates a text field using the given value and 'onChange' event handler. textFieldV :: WidgetEvent e => Text -> (Text -> e) -> WidgetNode s e textFieldV value handler = textFieldV_ value handler def --- | Creates a text field using the given value and onChange event handler. +-- | Creates a text field using the given value and 'onChange' event handler. -- Accepts config. textFieldV_ :: WidgetEvent e => Text -> (Text -> e) -> [TextFieldCfg s e] -> WidgetNode s e @@ -199,7 +203,7 @@ textFieldV_ value handler configs = textFieldD_ widgetData newConfig where widgetData = WidgetValue value newConfig = onChange handler : configs --- | Creates a text field providing a WidgetData instance and config. +-- | Creates a text field providing a 'WidgetData' instance and config. textFieldD_ :: WidgetEvent e => WidgetData s Text -> [TextFieldCfg s e] -> WidgetNode s e textFieldD_ widgetData configs = inputField where diff --git a/src/Monomer/Widgets/Singles/TimeField.hs b/src/Monomer/Widgets/Singles/TimeField.hs index 0ba53452..2b7a314f 100644 --- a/src/Monomer/Widgets/Singles/TimeField.hs +++ b/src/Monomer/Widgets/Singles/TimeField.hs @@ -15,25 +15,6 @@ Maybe is also supported. Supports different time formats. Handles mouse wheel and shift + vertical drag to increase/decrease minutes. - -Configs: - -- validInput: field indicating if the current input is valid. Useful to show -warnings in the UI, or disable buttons if needed. -- resizeOnChange: Whether input causes ResizeWidgets requests. -- selectOnFocus: Whether all input should be selected when focus is received. -- minValue: Minimum valid date. -- maxValue: Maximum valid date. -- wheelRate: The rate at which wheel movement affects the date. -- dragRate: The rate at which drag movement affects the date. -- onFocus: event to raise when focus is received. -- onFocusReq: WidgetRequest to generate when focus is received. -- onBlur: event to raise when focus is lost. -- onBlurReq: WidgetRequest to generate when focus is lost. -- onChange: event to raise when the value changes. -- onChangeReq: WidgetRequest to generate when the value changes. -- timeFormatHHMM: accepts HH:MM. -- timeFormatHHMMSS: accepts HH:MM:SS. -} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} @@ -43,6 +24,11 @@ warnings in the UI, or disable buttons if needed. {-# LANGUAGE UndecidableInstances #-} module Monomer.Widgets.Singles.TimeField ( + -- * Configuration + TimeFieldCfg, + FormattableTime, + TimeOfDayConverter(..), + -- * Constructors timeField, timeField_, timeFieldV, @@ -84,8 +70,8 @@ defaultTimeDelim :: Char defaultTimeDelim = ':' {-| -Converter to and form the TimeOfDay type of the time library. To use types other -than TimeOfDay of said library, this typeclass needs to be implemented. +Converter to and form the 'TimeOfDay' type of the time library. To use types +other than 'TimeOfDay' of said library, this typeclass needs to be implemented. --} class (Eq a, Ord a, Show a, Typeable a) => TimeOfDayConverter a where convertFromTimeOfDay :: TimeOfDay -> a @@ -95,6 +81,7 @@ instance TimeOfDayConverter TimeOfDay where convertFromTimeOfDay = id convertToTimeOfDay = Just +-- | Converts a 'TimeOfDay' instance to and from 'Text'. class TimeTextConverter a where timeAcceptText :: TimeFormat -> Maybe a -> Maybe a -> Text -> (Bool, Bool, Maybe a) timeFromText :: TimeFormat -> Text -> Maybe a @@ -132,9 +119,30 @@ instance (TimeOfDayConverter a, TimeTextConverter a) => TimeTextConverter (Maybe timeToTimeOfDay' Nothing = Nothing timeToTimeOfDay' (Just value) = timeToTimeOfDay' value +-- | Constraints for time types accepted by timeField. type FormattableTime a = (Eq a, Ord a, Show a, TimeTextConverter a, Typeable a) +{-| +Configuration options for timeField: + +- 'validInput': field indicating if the current input is valid. Useful to show +warnings in the UI, or disable buttons if needed. +- 'resizeOnChange': Whether input causes ResizeWidgets requests. +- 'selectOnFocus': Whether all input should be selected when focus is received. +- 'minValue': Minimum valid date. +- 'maxValue': Maximum valid date. +- 'wheelRate': The rate at which wheel movement affects the date. +- 'dragRate': The rate at which drag movement affects the date. +- 'onFocus': event to raise when focus is received. +- 'onFocusReq': 'WidgetRequest' to generate when focus is received. +- 'onBlur': event to raise when focus is lost. +- 'onBlurReq': 'WidgetRequest' to generate when focus is lost. +- 'onChange': event to raise when the value changes. +- 'onChangeReq': 'WidgetRequest' to generate when the value changes. +- 'timeFormatHHMM': accepts HH:MM. +- 'timeFormatHHMMSS': accepts HH:MM:SS. +-} data TimeFieldCfg s e a = TimeFieldCfg { _tfcCaretWidth :: Maybe Double, _tfcCaretMs :: Maybe Int, @@ -298,13 +306,13 @@ timeField_ timeField_ field configs = widget where widget = timeFieldD_ (WidgetLens field) configs --- | Creates a time field using the given value and onChange event handler. +-- | Creates a time field using the given value and 'onChange' event handler. timeFieldV :: (FormattableTime a, WidgetEvent e) => a -> (a -> e) -> WidgetNode s e timeFieldV value handler = timeFieldV_ value handler def --- | Creates a time field using the given value and onChange event handler. +-- | Creates a time field using the given value and 'onChange' event handler. -- Accepts config. timeFieldV_ :: (FormattableTime a, WidgetEvent e) @@ -317,7 +325,7 @@ timeFieldV_ value handler configs = newNode where newConfigs = onChange handler : configs newNode = timeFieldD_ widgetData newConfigs --- | Creates a time field providing a WidgetData instance and config. +-- | Creates a time field providing a 'WidgetData' instance and config. timeFieldD_ :: (FormattableTime a, WidgetEvent e) => WidgetData s a diff --git a/src/Monomer/Widgets/Util/Style.hs b/src/Monomer/Widgets/Util/Style.hs index 7abe3ebe..25b863ce 100644 --- a/src/Monomer/Widgets/Util/Style.hs +++ b/src/Monomer/Widgets/Util/Style.hs @@ -216,9 +216,9 @@ handleStyleChange wenv target style doCursor node evt result = newResult where Replacement of currentStyle for child widgets embedded in a focusable parent. It selects the correct style state according to the situation. -Used, for example, in `Button` and `ExternalLink`, which are focusable but have -an embedded label. Since label is not focusable, that style would not be handled -correctly. +Used, for example, in "Monomer.Widgets.Singles.Button" and +"Monomer.Widgets.Singles.ExternalLink", which are focusable but have an embedded +label. Since label is not focusable, that style would not be handled correctly. -} childOfFocusedStyle :: WidgetEnv s e -- ^ The widget environment.