WxHaskell/Layout

From HaskellWiki
Jump to navigation Jump to search

Layout

All details are based on using wxHaskell on Microsoft Windows XP.

Layout setting by gridding

In general, we can create layout by setting the layout argument in a frame or a panel, for example,

gui = do f <- frame [ text := "Layout" ]
         p <- panel f []
         b <- button p [ text := "button" ]
         set f [ layout := margin 2 $ container p $ floatCenter $
                              widget b
               , clientSize := sz 100 100
               ]


I will call this Layout setting by gridding.

Gridding means using the layout function, such as grid, row, column etc, to set the layout.

Layout setting by positioning

Also, we could set the layout by another way, Layout setting by positioning

gui = do f <- frame [ text := "Layout"
                    , clientSize := sz 100 100 ]
         p <- panel f [ clientSize := sz 98 98,
                      , position := pt 2 2 ]
         b <- button p [ text := "button"
                       , position := pt 45 45 ]


The result of both examples are about the same, only the button position has a bit different. (Please measure the exact position by yourself). By this way, we can have more flexible layout rather than limited the layout by grids.

EYK: it seems like layout by positioning allows for more precise control, but it does not seem like it would respond nicely to window resizing, no?

Layout reconfiguration

We can also re-configure the layout by just simply re-assign a new layout value to the layout. But remember, do not assign the same tab to the layout twice, it will append the same tab to the notebook. To prevent this, assign an empty list to the notebook

f <- frame [ text := "Layout" ]
nb <- notebook f []
set f [ layout := tabs nb [] ]


Transformers

fill = stretch . expand

NB: these are tentative explanations, could be wrong

Two dimensions are important here

shape (expansion)
the widget's shape: how does a widget use the space around it? Your options are
  • rigid (default): fixed shape
  • shaped expands but retains proportions
  • expand just expands without caring about proportions
stretch
the widget's dynamic behaviour: OK so your widget is laid out and has expanded however much it wants to. Now what happens when you give it even more space by resizing the parent window? Your options are
  • static (default): no stretching!
  • stretch, hstretch, vstretch: stretches perhaps along one dimension only
  • minsize (not sure how this behaves)

TODO: screenshots

dynamic

??? how does this relate to expand/stretch?

margin, boxed

Questions

  1. Where can you define layouts? The API says frames, panels, and dialogues, but is it seems like defining sub-layouts in panels is a bit problematic
  2. Wait, you mean I have to put all my layout in the frame? That's not very modular!

Troubleshooting

Not in right place

  • Checklist
    • Did you use layout? Declaring the widget is not enough. You have to tell wxHaskell where it fits in wrt other widgets in the window
    • Did you put the layout in the right parent? (elaborate)
    • Do you need to use one of hfloatRight and hfloatLeft?

Too small

  • Problem: really tiny frame when my app launches
    Solution: set clientSize
  • Problem: widgets do not resize when window is resized
    Solution: make sure you are using the stretch combinators. Remember that columns only (h)stretch if all their members (h)stretch, and similarly for rows and vstretch.

Too big

  • Problem absurdly huge widget
    Possible solution make sure the widget is placed in the correct parent.

See also

Button sizing - It has problems to set the size of button