ScrollableLayout.java

net.minecraft.client.gui.components.ScrollableLayout

信息

  • 全限定名:net.minecraft.client.gui.components.ScrollableLayout
  • 类型:public class
  • 包:net.minecraft.client.gui.components
  • 源码路径:src/main/java/net/minecraft/client/gui/components/ScrollableLayout.java
  • 起始行号:L23
  • 实现:Layout
  • 职责:

    TODO

字段/常量

  • DEFAULT_SCROLLBAR_SPACING

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L24
    • 说明:

      TODO

  • content

    • 类型: Layout
    • 修饰符: private final
    • 源码定位: L25
    • 说明:

      TODO

  • container

    • 类型: ScrollableLayout.Container
    • 修饰符: private final
    • 源码定位: L26
    • 说明:

      TODO

  • reserveStrategy

    • 类型: ScrollableLayout.ReserveStrategy
    • 修饰符: private final
    • 源码定位: L27
    • 说明:

      TODO

  • scrollbarSpacing

    • 类型: int
    • 修饰符: private final
    • 源码定位: L28
    • 说明:

      TODO

  • minWidth

    • 类型: int
    • 修饰符: private
    • 源码定位: L29
    • 说明:

      TODO

  • minHeight

    • 类型: int
    • 修饰符: private
    • 源码定位: L30
    • 说明:

      TODO

  • maxHeight

    • 类型: int
    • 修饰符: private
    • 源码定位: L31
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.gui.components.ScrollableLayout.Container

    • 类型: class
    • 修饰符: private
    • 源码定位: L107
    • 说明:

      TODO

  • net.minecraft.client.gui.components.ScrollableLayout.ReserveStrategy

    • 类型: enum
    • 修饰符: public static
    • 源码定位: L200
    • 说明:

      TODO

构造器

public ScrollableLayout(Minecraft minecraft, Layout content, int maxHeight) @ L33

  • 构造器名:ScrollableLayout
  • 源码定位:L33
  • 修饰符:public

参数:

  • minecraft: Minecraft
  • content: Layout
  • maxHeight: int

说明:

TODO

方法

下面的方法块按源码顺序生成。

public void setMinWidth(int minWidth) @ L41

  • 方法名:setMinWidth
  • 源码定位:L41
  • 返回类型:void
  • 修饰符:public

参数:

  • minWidth: int

说明:

TODO

public void setMinHeight(int minHeight) @ L46

  • 方法名:setMinHeight
  • 源码定位:L46
  • 返回类型:void
  • 修饰符:public

参数:

  • minHeight: int

说明:

TODO

public void setMaxHeight(int maxHeight) @ L51

  • 方法名:setMaxHeight
  • 源码定位:L51
  • 返回类型:void
  • 修饰符:public

参数:

  • maxHeight: int

说明:

TODO

public void arrangeElements() @ L57

  • 方法名:arrangeElements
  • 源码定位:L57
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void visitChildren(Consumer<LayoutElement> layoutElementVisitor) @ L71

  • 方法名:visitChildren
  • 源码定位:L71
  • 返回类型:void
  • 修饰符:public

参数:

  • layoutElementVisitor: Consumer

说明:

TODO

public void setX(int x) @ L76

  • 方法名:setX
  • 源码定位:L76
  • 返回类型:void
  • 修饰符:public

参数:

  • x: int

说明:

TODO

public void setY(int y) @ L81

  • 方法名:setY
  • 源码定位:L81
  • 返回类型:void
  • 修饰符:public

参数:

  • y: int

说明:

TODO

public int getX() @ L86

  • 方法名:getX
  • 源码定位:L86
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getY() @ L91

  • 方法名:getY
  • 源码定位:L91
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getWidth() @ L96

  • 方法名:getWidth
  • 源码定位:L96
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getHeight() @ L101

  • 方法名:getHeight
  • 源码定位:L101
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class ScrollableLayout implements Layout {
    private static final int DEFAULT_SCROLLBAR_SPACING = 4;
    private final Layout content;
    private final ScrollableLayout.Container container;
    private final ScrollableLayout.ReserveStrategy reserveStrategy;
    private final int scrollbarSpacing;
    private int minWidth;
    private int minHeight;
    private int maxHeight;
 
    public ScrollableLayout(Minecraft minecraft, Layout content, int maxHeight) {
        this.content = content;
        this.maxHeight = maxHeight;
        this.reserveStrategy = ScrollableLayout.ReserveStrategy.BOTH;
        this.scrollbarSpacing = 4;
        this.container = new ScrollableLayout.Container(minecraft, 0, maxHeight, AbstractScrollArea.defaultSettings(10));
    }
 
    public void setMinWidth(int minWidth) {
        this.minWidth = minWidth;
        this.container.setWidth(Math.max(this.content.getWidth(), minWidth));
    }
 
    public void setMinHeight(int minHeight) {
        this.minHeight = minHeight;
        this.container.setHeight(Math.max(this.content.getHeight(), minHeight));
    }
 
    public void setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
        this.container.setHeight(Math.min(this.content.getHeight(), maxHeight));
        this.container.refreshScrollAmount();
    }
 
    @Override
    public void arrangeElements() {
        this.content.arrangeElements();
        int contentWidth = this.content.getWidth();
 
        int scrollbarReserve = switch (this.reserveStrategy) {
            case RIGHT -> this.container.scrollbarReserve();
            case BOTH -> 2 * this.container.scrollbarReserve();
        };
        this.container.setWidth(Math.max(contentWidth, this.minWidth) + scrollbarReserve);
        this.container.setHeight(Math.clamp((long)this.container.getHeight(), this.minHeight, this.maxHeight));
        this.container.refreshScrollAmount();
    }
 
    @Override
    public void visitChildren(Consumer<LayoutElement> layoutElementVisitor) {
        layoutElementVisitor.accept(this.container);
    }
 
    @Override
    public void setX(int x) {
        this.container.setX(x);
    }
 
    @Override
    public void setY(int y) {
        this.container.setY(y);
    }
 
    @Override
    public int getX() {
        return this.container.getX();
    }
 
    @Override
    public int getY() {
        return this.container.getY();
    }
 
    @Override
    public int getWidth() {
        return this.container.getWidth();
    }
 
    @Override
    public int getHeight() {
        return this.container.getHeight();
    }
 
    @OnlyIn(Dist.CLIENT)
    private class Container extends AbstractContainerWidget {
        private final Minecraft minecraft;
        private final List<AbstractWidget> children;
 
        public Container(Minecraft minecraft, int width, int height, AbstractScrollArea.ScrollbarSettings scrollbarSettings) {
            Objects.requireNonNull(ScrollableLayout.this);
            super(0, 0, width, height, CommonComponents.EMPTY, scrollbarSettings);
            this.children = new ArrayList<>();
            this.minecraft = minecraft;
            ScrollableLayout.this.content.visitWidgets(this.children::add);
        }
 
        @Override
        protected int contentHeight() {
            return ScrollableLayout.this.content.getHeight();
        }
 
        @Override
        protected void extractWidgetRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
            graphics.enableScissor(this.getX(), this.getY(), this.getX() + this.width, this.getY() + this.height);
 
            for (AbstractWidget child : this.children) {
                child.extractRenderState(graphics, mouseX, mouseY, a);
            }
 
            graphics.disableScissor();
            this.extractScrollbar(graphics, mouseX, mouseY);
        }
 
        @Override
        protected void updateWidgetNarration(NarrationElementOutput output) {
        }
 
        @Override
        public ScreenRectangle getBorderForArrowNavigation(ScreenDirection opposite) {
            GuiEventListener focused = this.getFocused();
            return focused != null
                ? focused.getBorderForArrowNavigation(opposite)
                : new ScreenRectangle(this.getX(), this.getY(), this.width, this.contentHeight()).getBorder(opposite);
        }
 
        @Override
        public void setFocused(@Nullable GuiEventListener focused) {
            super.setFocused(focused);
            if (focused != null && this.minecraft.getLastInputType().isKeyboard()) {
                ScreenRectangle area = this.getRectangle();
                ScreenRectangle focusedRect = focused.getRectangle();
                int topDelta = focusedRect.top() - area.top();
                int bottomDelta = focusedRect.bottom() - area.bottom();
                double scrollRate = this.scrollRate();
                if (topDelta < 0) {
                    this.setScrollAmount(this.scrollAmount() + topDelta - scrollRate);
                } else if (bottomDelta > 0) {
                    this.setScrollAmount(this.scrollAmount() + bottomDelta + scrollRate);
                }
            }
        }
 
        @Override
        public void setX(int x) {
            super.setX(x);
            ScrollableLayout.this.content
                .setX(x + (ScrollableLayout.this.reserveStrategy == ScrollableLayout.ReserveStrategy.BOTH ? this.scrollbarReserve() : 0));
        }
 
        @Override
        public void setY(int y) {
            super.setY(y);
            ScrollableLayout.this.content.setY(y - (int)this.scrollAmount());
        }
 
        private int scrollbarReserve() {
            return ScrollableLayout.this.scrollbarSpacing + this.scrollbarWidth();
        }
 
        @Override
        public void setScrollAmount(double scrollAmount) {
            super.setScrollAmount(scrollAmount);
            ScrollableLayout.this.content.setY(this.getRectangle().top() - (int)this.scrollAmount());
        }
 
        @Override
        public List<? extends GuiEventListener> children() {
            return this.children;
        }
 
        @Override
        public Collection<? extends NarratableEntry> getNarratables() {
            return this.children;
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public static enum ReserveStrategy {
        RIGHT,
        BOTH;
    }
}

引用的其他类