Skip to main content

Panels & Layout

Coming from Data Display, this page is a little different from the rest — every control here exists to arrange other Views, rather than show a value of its own.

Which one do you actually want?

If you need...Reach for
A View too big for its space, scrollable rather than resizedScrollPanel
A grid of rows and columnsGridPanel
Two resizable areas, side by sideSplitPanel
One of several Views visible at a time, tab-styleTabbedPanel
One of several sections visible at a time, vertically stackedAccordion
tip

All five of these are really just pre-built Layouts for common arrangements. If your layout doesn't fit any of them — an irregular arrangement, say — writing constraints by hand is still completely reasonable. These controls exist to save you the trouble for the shapes that come up constantly, not to be the only way to arrange Views.

ScrollPanel​

The simplest of the bunch: wraps a single content View, clips it to the panel's bounds, and scrolls it when it's too big to fit — rather than squeezing or resizing it the way GridPanel or SplitPanel might. Set content any time, and contentChanged notifies you when it does.

package controls import io.nacular.doodle.controls.panels.ScrollPanel import io.nacular.doodle.core.View import io.nacular.doodle.layout.constraints.ideal fun scrollPanel(bigView: View) { //sampleStart val panel = ScrollPanel(content = bigView).apply { contentConstraints = { it.width eq parent.width - verticalScrollBarWidth it.height hint ideal } } //sampleEnd }

A property worth knowing about control how the content behaves as the panel itself resizes: contentConstraints — it is a small function returning a constraint, so you can pin the content to the panel's exact width while letting its height scroll freely, say.

tip

This is exactly what powers the scrolling form control from Form Controls, and it's what TabbedPanel's ScrollPanelVisualizer (just below) wraps tab content in.

nativeScrollPanelBehavior (Web, Desktop)

GridPanel​

Arranges children into a grid of rows and columns — the control version of the constraint-based grids you'd otherwise build by hand on the Constraints page, packaged up for the common case. Each item you add declares the row and column it sits at, plus how many rows and columns it spans — a 2×1 item to span two columns, say. Those spans, together with the panel's rowSizingPolicy and columnSizingPolicy, are what ultimately decide how everything gets sized.

SplitPanel​

Divides a region into two areas, each holding one View, with a draggable divider letting the user resize the split between them. Nest one inside another to build more complex arrangements — a horizontal split whose second half is itself a vertical split, for instance.

This shows how you might nest horizontal and vertical SplitPanels.

tip

Requires a SplitPanelBehavior for rendering. BasicTheme provides one.

TabbedPanel​

Shows one of several items at a time, switched between with tabs. It takes two ItemVisualizers — one turns each item into the little tab you click, the other turns it into the main content shown underneath. With basicTabbedPanelBehavior, that main content gets scaled to fit the panel; wrap it in a ScrollPanelVisualizer instead if your tabs are meant to hold arbitrary Views that shouldn't be squeezed to fit.

This is also the control used as the running example on the Theming page for just how much a Behavior can take on — worth a look if you're customizing one heavily.

tip

This control requires a TabbedPanelBehavior for rendering. This demo uses the basicTabbedPanelBehavior module which installs BasicTabbedPanelBehavior

Accordion​

Like TabbedPanel in spirit — several sections, one focus at a time, and the same two-visualizer split (one for the section header, one for its content) — but stacked vertically with expand/collapse instead of side-by-side tabs. Reach for this over TabbedPanel when your sections read naturally as a list rather than parallel pages.

tip

Switching between tabs or expanding a section feels abrupt with no transition. If you're writing a custom Behavior for either control, Animation — tweening a size or position as the switch happens — is what makes it glide instead of snap.

Recap​

Next: on to Media & Pickers for images, files, and specialized selection controls.