Class ScrollGutters

java.lang.Object
limn.components.ScrollGutters

public final class ScrollGutters extends Object
How much of a scrolling widget's box its scrollbars take, and the settling that decides it. Owned by the widget, one instance each: ScrollView, ListView and TextArea all hold one, and so should anything else that scrolls.

 // in onLayout, where `content` re-measures into a viewport:
 Size size = gutters.resolve(width(), height(), vBar, hBar,
         (viewW, viewH) -> child.measure(Constraints.loose(viewW, viewH)));
 float viewW = gutters.viewportWidth(width());
 

The class exists because three widgets needed the same three paragraphs of reasoning, and a rule copied three times is a rule that will differ three ways within a year. What is genuinely per-widget (how content is measured, where rows are placed, what gets clipped) stays with the widget; what is identical (when a strip is reserved and how wide) lives here.

  • Constructor Details

    • ScrollGutters

      public ScrollGutters()
  • Method Details

    • setLayout

      public void setLayout(ScrollGutters.Layout newLayout)
      Sets the mode (default ScrollGutters.Layout.OVERLAY); the host asks for the relayout.
    • layout

      public ScrollGutters.Layout layout()
      Whether the bars overlay the content or reserve a gutter beside it.
    • verticalStrip

      public float verticalStrip()
      Width taken by the vertical bar, or 0 when it floats or is not needed.
    • horizontalStrip

      public float horizontalStrip()
      Height taken by the horizontal bar, likewise.
    • viewportWidth

      public float viewportWidth(float boxWidth)
      Width left for content, the full box when the bars overlay it.
    • viewportHeight

      public float viewportHeight(float boxHeight)
      Height left for content, the full box when the bars overlay it.
    • resolve

      public Size resolve(float boxWidth, float boxHeight, ScrollBar vBar, ScrollBar hBar, ScrollGutters.Content content)
      Settles the strips for a box and returns the content's size in the viewport they leave. Pass null for an axis the widget does not scroll.

      Two passes, and it refuses a third. Reserving a strip narrows the content, which can make it taller (wrapped text is the everyday case) and turn an axis that fitted into one that overflows; the second pass sees that. A third is where content whose two axes disagree about which bar they need would oscillate forever, and one bar more than strictly necessary is a better outcome than a layout that never settles.

      The strips key on overflow, not on whether a bar is currently drawn. Under the fading policies a bar comes and goes constantly, and reserving by visibility would rewrap the content under the pointer every time it did.