| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Geomancy.Layout.View
Description
SwiftUI-like view tree
The layout keeps the propose-report-place protocol, but chops some parts away.
- Views are abstracted and the
Viewconstructor punches a hole in a tree (a hollow?) for a UI toolkit to fill in later. - There's no "tree builder", so containers and modifiers are constructed directly. Although it is easy to recover modifier with the "Data.Function.(&)" operator.
- There's no "ideal size", "fixed size" etc. and the views are fully flexible. The UI tookit wrappers can instead self-wrap their Views in a
Frame/FlexibleFrameas needed.
Synopsis
- layout :: LayoutView stuff => Box -> View () stuff -> View Box (Placed stuff)
- foldWith :: (LayoutView stuff, Monoid a) => (Placed stuff -> a) -> Box -> View () stuff -> a
- class LayoutView stuff where
- type ReportedCache stuff
- type Placed stuff
- viewFlexibility :: stuff -> ViewSize
- proposeView :: Vec2 -> stuff -> (Vec2, ReportedCache stuff)
- placeView :: Box -> ReportedCache stuff -> Placed stuff
- data ViewFun stuff = ViewFun ViewSize (Vec2 -> (Vec2, Box -> stuff))
- viewFun :: ViewSize -> (Vec2 -> (Vec2, Box -> stuff)) -> View () (ViewFun stuff)
- boxFun :: (Box -> stuff) -> View () (ViewFun stuff)
- data View ann stuff
- view_ :: stuff -> View () stuff
- spacer_ :: View () stuff
- hstack_ :: [View () stuff] -> View () stuff
- vstack_ :: [View () stuff] -> View () stuff
- zstack_ :: [View () stuff] -> View () stuff
- overlay_ :: View () stuff -> View () stuff -> View () stuff
- frame_ :: Vec2 -> View () stuff -> View () stuff
- flexible_ :: ViewSize -> Alignment -> View () stuff -> View () stuff
- aspect_ :: Vec2 -> View () stuff -> View () stuff
- padding_ :: Vec4 -> View () stuff -> View () stuff
- offset_ :: Vec2 -> View () stuff -> View () stuff
- data ViewSize = ViewSize {}
- fixed_ :: Vec2 -> ViewSize
- infinite_ :: ViewSize
- range_ :: Vec2 -> Vec2 -> ViewSize
- parent_ :: ViewSize
- parentWidth :: ViewSize -> ViewSize
- parentHeight :: ViewSize -> ViewSize
- measure :: LayoutView stuff => View () stuff -> View ViewSize stuff
- place :: LayoutView stuff => Box -> View ViewSize stuff -> View Box (Placed stuff)
- suspend :: LayoutView stuff => Vec2 -> View ViewSize stuff -> (Vec2, Box -> View Box (Placed stuff))
- inf :: Float
- widthFlexibility :: ViewSize -> Float
- heightFlexibility :: ViewSize -> Float
- vsClamp :: Vec2 -> ViewSize -> Vec2 -> Vec2
- maybeBoth :: t1 -> (t2 -> t3 -> t1) -> Maybe t2 -> Maybe t3 -> t1
- combineH :: Vec2 -> Vec2 -> Vec2
- combineV :: Vec2 -> Vec2 -> Vec2
- max2 :: Vec2 -> Vec2 -> Vec2
Documentation
layout :: LayoutView stuff => Box -> View () stuff -> View Box (Placed stuff) Source #
Run all the layout steps to annotate the nodes with their final placement boxes.
foldWith :: (LayoutView stuff, Monoid a) => (Placed stuff -> a) -> Box -> View () stuff -> a Source #
Do all of the layout steps and fold placed views
Mostly an example. The better way is to cache intermediate steps.
(Actually a pun on "fold views".)
class LayoutView stuff where Source #
An interface to plug UI toolkits into the layout.
Alternatively, convert them to ViewFun, which has the instance.
The "minimal: none" is a lie. Most likely you will need to adjust either 'ReportedCache ' or Placed types and implement the other function accordingly.
The most gnarly code would be for "rendered text" widgets since they would be dynamically sized and have to be processed/cached on each step.
Minimal complete definition
Nothing
Associated Types
type ReportedCache stuff Source #
type ReportedCache stuff = stuff
type Placed stuff = stuff
Methods
viewFlexibility :: stuff -> ViewSize Source #
Measurement pre-pass
default viewFlexibility :: stuff -> ViewSize Source #
Default implementation is "the view *will* adapt to any size"
proposeView :: Vec2 -> stuff -> (Vec2, ReportedCache stuff) Source #
Propose step: return the actual size and store intermediate data.
default proposeView :: ReportedCache stuff ~ stuff => Vec2 -> stuff -> (Vec2, ReportedCache stuff) Source #
Default implementation for "accept everything" reporting
placeView :: Box -> ReportedCache stuff -> Placed stuff Source #
Placement step: get the reported size augmented with a final position, produce the result.
default placeView :: ReportedCache stuff ~ (Box -> Placed stuff) => Box -> ReportedCache stuff -> Placed stuff Source #
Default implementation for "box function" placement
Instances
| LayoutView (Identity stuff) Source # | Do-nothing pass-through instance You'll have to peek at the | ||||||||
Defined in Geomancy.Layout.View Associated Types
| |||||||||
| LayoutView (ViewFun stuff) Source # | |||||||||
Defined in Geomancy.Layout.View Associated Types
| |||||||||
| (LayoutView l, LayoutView r) => LayoutView (Either l r) Source # | "Variant-lite" instance to mix widgets of different type XXX: the foldable/traversable would skip the Lefts.
Use something like | ||||||||
Defined in Geomancy.Layout.View Associated Types
| |||||||||
A model type for the protocol
The fields correspond to the 3 steps:
- Measurement into ViewSize - static.
- Proposing and reporting - depends on parent size / caches size-related data.
- Placement - depends on placement (
Box= reported size + position), can use cached data.
Instances
| Functor ViewFun Source # | |||||||||
| LayoutView (ViewFun stuff) Source # | |||||||||
Defined in Geomancy.Layout.View Associated Types
| |||||||||
| type Placed (ViewFun stuff) Source # | |||||||||
Defined in Geomancy.Layout.View | |||||||||
| type ReportedCache (ViewFun stuff) Source # | |||||||||
Defined in Geomancy.Layout.View | |||||||||
viewFun :: ViewSize -> (Vec2 -> (Vec2, Box -> stuff)) -> View () (ViewFun stuff) Source #
A wrapper to construct ViewFun-based views
boxFun :: (Box -> stuff) -> View () (ViewFun stuff) Source #
A wrapper to construct ViewFun-based views by assuming infinite flex and no intrinsic size
View tree
Layout skeleton
It is Functor-Foldable-Traversable on View so you can use things like void to suppress payload and show the intermediate structure.
Constructors
| View | UI-specific payload |
| Spacer | |
Fields
| |
| HStack | Place children side-by-side (LTR) |
| VStack | Place children top-to-bottom |
| ZStack | Place children atop of each other |
| Overlay | Propose the size of the primary view to the secondary view |
| Frame | Propose/report size unconditionally |
| FlexibleFrame | |
| AspectRatio | |
| Padding | Subtracts a CSS-tyle padding (toprightbottom/left) from parent |
| Offset | Adds offset when placing a view |
Instances
| Bifunctor View Source # | |
| Foldable (View ann) Source # | |
Defined in Geomancy.Layout.View Methods fold :: Monoid m => View ann m -> m # foldMap :: Monoid m => (a -> m) -> View ann a -> m # foldMap' :: Monoid m => (a -> m) -> View ann a -> m # foldr :: (a -> b -> b) -> b -> View ann a -> b # foldr' :: (a -> b -> b) -> b -> View ann a -> b # foldl :: (b -> a -> b) -> b -> View ann a -> b # foldl' :: (b -> a -> b) -> b -> View ann a -> b # foldr1 :: (a -> a -> a) -> View ann a -> a # foldl1 :: (a -> a -> a) -> View ann a -> a # elem :: Eq a => a -> View ann a -> Bool # maximum :: Ord a => View ann a -> a # minimum :: Ord a => View ann a -> a # | |
| Traversable (View ann) Source # | |
| Functor (View ann) Source # | |
| (Show stuff, Show ann) => Show (View ann stuff) Source # | |
| (Eq stuff, Eq ann) => Eq (View ann stuff) Source # | |
Some shortcuts
Containers
Modifiers
Flexibility helper
parentWidth :: ViewSize -> ViewSize Source #
parentHeight :: ViewSize -> ViewSize Source #
Layout steps
place :: LayoutView stuff => Box -> View ViewSize stuff -> View Box (Placed stuff) Source #
Run the propose-report-place protocol on a flex-measured view tree
suspend :: LayoutView stuff => Vec2 -> View ViewSize stuff -> (Vec2, Box -> View Box (Placed stuff)) Source #
Propose-Report-Place protocol using continuations
Inner children can't be placed until the whole propose-report dance finishes.
Internals
widthFlexibility :: ViewSize -> Float Source #
heightFlexibility :: ViewSize -> Float Source #