Message Boards Message Boards


Create (Header + Main area + Settings pane) notebook layout?

Posted 4 years ago
5 Replies
16 Total Likes

cross-posted in mathematica.stackexchange

The goal is something like in the picture below.

Basic? I dare you to try to implement it in a manageable, scalable and flexible way.

enter image description here


The goal is a natural experience as this is a standard layout in many places. Keep that in mind if anything is not clear.

Points 1. and 2. are required. 3. is optional.

  1. Behavior:

    • 'head' has fixed heigth and notebook's width (minus margins). Would be nice to not have to know the height before.

    • notebook is resizeable and when it happens:

    • 'main' and 'sett' adapt heights to fill the notebook

    • 'sett' width remains the same, only 'main's' width is affected

    • 'sett's' width can be changed by inner 'resizeArea' element. (not present above, usually one can dragg the vertical area between 'main' and 'sett' but how it will be done here does not matter.

    • needs to work well at least on Mac and Win

    • needs to work in a .cdf launched inside FreePlayer

    • needs to work smoothly as this is only a template for further app, perfect solution would be completely FrontEnd side but it is enough if panels' contents are not bothered too much

  2. Style: (equally important)

    • panel's frames need to be aligned (like above)

    • margins/spacings/cellmargins should be consistent. e.g. outer margins should be the same as spaces between panels inside, or whatever user desires.

  3. Bonus points for:

    • easily adaptable for different window frames e.g.: palette/default.

    • max/min notebook size restrictions

    • should handle magnification changes gracefully, e.g. panel layout should be left intact or scale notebook size together with it, while contents of panels should scale normally


The ideal answer should provide a general approach for multipanel layout that supports resizing/locking specific values and the final result is aligned nicely with adjustable margins etc.

A good test case would be to handle something like:

  {"header", SpanFromLeft, SpanFromLeft},
  {"left panel", Pane["main panel", ImageSize -> {300, 300}, Alignment -> {Center, Center}], "rightPanel"},
  {"footer", SpanFromLeft}
  }, Frame -> All]

What have you tried?

A lot... and I always ended up with a really project specific solution that needed to sacrifice few features. I lost hope for Full/Scaled ImageSize spec, in terms of expected response, respecting margins or scalability for multiple panels.

Managing image size via Dynamic ImageSize for Panes quickly escalates to not worth the effort stage. And is not stable, I can cook up and example which works well till you move the window to a secondary screen... despite the fact it only uses WindowSize.

Here is something to start with:

  DynamicModule[{headerH = 50, settW = 150}
  , Grid[
      { { Panel@ Pane["head", Dynamic@{AbsoluteCurrentValue[{WindowSize, 1}] - 28, headerH}]
        , SpanFromLeft
      , { Panel @ Pane["main", Dynamic[AbsoluteCurrentValue[
            WindowSize] - {settW + 15 + 18 + 12, headerH + 15 + 18 + 12}]]
        , Panel @ Pane["sett", Dynamic[{settW, AbsoluteCurrentValue[{WindowSize, 2}] - headerH - 15 - 18 -  12}]]
    , Spacings -> {0, 0}
    , Alignment -> {Left, Top}
  , BaseStyle -> {
      PanelBoxOptions -> {
        FrameMargins -> 0, ImageMargins -> 5, BaseStyle -> FontSize -> 25
    , PaneBoxOptions -> {FrameMargins -> 0, ImageMargins -> 0
      , Alignment -> {Center, Center}
, WindowSize -> 500
, StyleDefinitions -> "Dialog.nb"
, CellMargins -> {{5, 5}, {5, 5}}
, CellFrameMargins -> {{0, 0}, {0, 0}}
, WindowFrameElements -> All

Additional reading:

5 Replies

One suggestion that might help: you can have any structure or element that takes sizing options that respond to the size of the notebook window the element is in, using dynamic formulas for options that reference WindowSize as a variable:

  "You can have any structure or element that takes sizing options that respond to the size of the notebook window the element is in, using dynamic formulas for options that reference WindowSize as a variable."], 
 ImageSize -> {Dynamic[First@CurrentValue[WindowSize] .2], 250} ]

Yes, I know, my example already contains AbsoluteCurrentValue[WindowSize].

The devil is in details though:

  • We want to have consistent margins around as well as between frames. To achieve that we need to know Notebook's frame widths (direction, OS and FrameElements dependent...). Otherwise the full content will exceed the window from the right side (unless every possible margin is set 0 or unless scaled sizes do not sum up to 100% and we are left with a scaled gap).

  • We also want to be able to resize inner panels, so we need to use Pane as only that gui element has ResizeArea. That is fine but it does not have Frame option (or background) so we need to wrap it with Panel or Framed and now hell begins... Since we want spacings between panels we need ImageMargins for those Panel/Framed-s. Pane's ImageSize will not account for that so it is another value we need to know and manage.

  • If this is not enough, notice that ImageSize arithmetic does not make sense (at least on Win):

    Grid[{#}, Spacings -> {0, 0}] & /@ Table[
       Framed["-", ImageSize -> {250/t, 50}, ImageMargins -> 0], 
       {t,  1, 10}, {n, 1, t}
    ] // Column // Framed

enter image description here

Which means we have another value to account for, this one is also number of elements in a row dependent.

Here is what could make gui developers lives easier:

  • CurrentValue[ NotebookContentSize ], WindowSize without notebook frame, I can manage CellMargins by myself.

  • Flexibility in specifying whether Scaled/Full ImageSize should respect FrameMargins/ImageMargins

  • like element that will gather functionality from Pane/Framed and friends, that is ResizeArea/Frame/Background. If introduced it should have all margins/styles/etc set to 0 / {} / None etc, bare rectangular area without any surprises.

  • Spacings and friends support for printers points (<cough>pixels on windows</cough>)

Any update will help, at this point I will take anything

I forgot to mention longstanding bugs that will make your life miserable if you start implementing this manually.

Avoiding sizes recalculations and re-rendering is crucial but those bugs make it tough/impossible:

I don't want to be picky I just want to show that there are fundamental problems which are ignored for a long time.

This plus lack of (visible/documented) updates for desktop's FrontEnd make me wonder, is WRI planning to replace it or is this a result of shifting humanpower towards Cloud's FrontEnd and iOS's?

Posted 4 years ago

To add to this, the lack of documented support for AttachedCells is a big pain. They could make this process much easier, but I don't really want to mess with them too much until they become documented because I don't know what bugs are hiding in them.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract