TabNavigationBar.java
net.minecraft.client.gui.components.tabs.TabNavigationBar
信息
- 全限定名:net.minecraft.client.gui.components.tabs.TabNavigationBar
- 类型:public class
- 包:net.minecraft.client.gui.components.tabs
- 源码路径:src/main/java/net/minecraft/client/gui/components/tabs/TabNavigationBar.java
- 起始行号:L33
- 继承:AbstractContainerEventHandler
- 实现:NarratableEntry, Renderable
- 职责:
TODO
字段/常量
-
NO_TAB- 类型:
int - 修饰符:
private static final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
MAX_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
HEIGHT- 类型:
int - 修饰符:
private static final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
MARGIN- 类型:
int - 修饰符:
private static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
USAGE_NARRATION- 类型:
Component - 修饰符:
private static final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
layout- 类型:
LinearLayout - 修饰符:
private final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
width- 类型:
int - 修饰符:
private - 源码定位:
L40 - 说明:
TODO
- 类型:
-
tabManager- 类型:
TabManager - 修饰符:
private final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
tabs- 类型:
ImmutableList<Tab> - 修饰符:
private final - 源码定位:
L42 - 说明:
TODO
- 类型:
-
tabButtons- 类型:
ImmutableList<TabButton> - 修饰符:
private final - 源码定位:
L43 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.client.gui.components.tabs.TabNavigationBar.Builder- 类型:
class - 修饰符:
public static - 源码定位:
L256 - 说明:
TODO
- 类型:
构造器
private TabNavigationBar(int width, TabManager tabManager, Iterable<Tab> tabs) @ L45
- 构造器名:TabNavigationBar
- 源码定位:L45
- 修饰符:private
参数:
- width: int
- tabManager: TabManager
- tabs: Iterable
说明:
TODO
方法
下面的方法块按源码顺序生成。
public static TabNavigationBar.Builder builder(TabManager tabManager, int width) @ L59
- 方法名:builder
- 源码定位:L59
- 返回类型:TabNavigationBar.Builder
- 修饰符:public static
参数:
- tabManager: TabManager
- width: int
说明:
TODO
public void updateWidth(int width) @ L63
- 方法名:updateWidth
- 源码定位:L63
- 返回类型:void
- 修饰符:public
参数:
- width: int
说明:
TODO
public boolean isMouseOver(double mouseX, double mouseY) @ L68
- 方法名:isMouseOver
- 源码定位:L68
- 返回类型:boolean
- 修饰符:public
参数:
- mouseX: double
- mouseY: double
说明:
TODO
public void setFocused(boolean focused) @ L76
- 方法名:setFocused
- 源码定位:L76
- 返回类型:void
- 修饰符:public
参数:
- focused: boolean
说明:
TODO
public void setFocused(GuiEventListener focused) @ L84
- 方法名:setFocused
- 源码定位:L84
- 返回类型:void
- 修饰符:public
参数:
- focused: GuiEventListener
说明:
TODO
public ComponentPath nextFocusPath(FocusNavigationEvent navigationEvent) @ L92
- 方法名:nextFocusPath
- 源码定位:L92
- 返回类型:ComponentPath
- 修饰符:public
参数:
- navigationEvent: FocusNavigationEvent
说明:
TODO
public List<?extends GuiEventListener> children() @ L104
- 方法名:children
- 源码定位:L104
- 返回类型:List<?extends GuiEventListener>
- 修饰符:public
参数:
- 无
说明:
TODO
public List<Tab> getTabs() @ L109
- 方法名:getTabs
- 源码定位:L109
- 返回类型:List
- 修饰符:public
参数:
- 无
说明:
TODO
public NarratableEntry.NarrationPriority narrationPriority() @ L113
- 方法名:narrationPriority
- 源码定位:L113
- 返回类型:NarratableEntry.NarrationPriority
- 修饰符:public
参数:
- 无
说明:
TODO
public void updateNarration(NarrationElementOutput output) @ L118
- 方法名:updateNarration
- 源码定位:L118
- 返回类型:void
- 修饰符:public
参数:
- output: NarrationElementOutput
说明:
TODO
protected void narrateListElementPosition(NarrationElementOutput output, TabButton widget) @ L134
- 方法名:narrateListElementPosition
- 源码定位:L134
- 返回类型:void
- 修饰符:protected
参数:
- output: NarrationElementOutput
- widget: TabButton
说明:
TODO
public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L143
- 方法名:extractRenderState
- 源码定位:L143
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- mouseX: int
- mouseY: int
- a: float
说明:
TODO
public ScreenRectangle getRectangle() @ L176
- 方法名:getRectangle
- 源码定位:L176
- 返回类型:ScreenRectangle
- 修饰符:public
参数:
- 无
说明:
TODO
public void arrangeElements() @ L181
- 方法名:arrangeElements
- 源码定位:L181
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void selectTab(int index, boolean playSound) @ L194
- 方法名:selectTab
- 源码定位:L194
- 返回类型:void
- 修饰符:public
参数:
- index: int
- playSound: boolean
说明:
TODO
public void setTabActiveState(int index, boolean active) @ L202
- 方法名:setTabActiveState
- 源码定位:L202
- 返回类型:void
- 修饰符:public
参数:
- index: int
- active: boolean
说明:
TODO
public void setTabTooltip(int index, Tooltip hint) @ L208
- 方法名:setTabTooltip
- 源码定位:L208
- 返回类型:void
- 修饰符:public
参数:
- index: int
- hint: Tooltip
说明:
TODO
public boolean keyPressed(KeyEvent event) @ L214
- 方法名:keyPressed
- 源码定位:L214
- 返回类型:boolean
- 修饰符:public
参数:
- event: KeyEvent
说明:
TODO
private int getNextTabIndex(KeyEvent event) @ L227
- 方法名:getNextTabIndex
- 源码定位:L227
- 返回类型:int
- 修饰符:private
参数:
- event: KeyEvent
说明:
TODO
private int getNextTabIndex(int currentTab, KeyEvent event) @ L231
- 方法名:getNextTabIndex
- 源码定位:L231
- 返回类型:int
- 修饰符:private
参数:
- currentTab: int
- event: KeyEvent
说明:
TODO
private int currentTabIndex() @ L244
- 方法名:currentTabIndex
- 源码定位:L244
- 返回类型:int
- 修饰符:private
参数:
- 无
说明:
TODO
private TabButton currentTabButton() @ L250
- 方法名:currentTabButton
- 源码定位:L250
- 返回类型:TabButton
- 修饰符:private
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class TabNavigationBar extends AbstractContainerEventHandler implements NarratableEntry, Renderable {
private static final int NO_TAB = -1;
private static final int MAX_WIDTH = 400;
private static final int HEIGHT = 24;
private static final int MARGIN = 14;
private static final Component USAGE_NARRATION = Component.translatable("narration.tab_navigation.usage");
private final LinearLayout layout = LinearLayout.horizontal();
private int width;
private final TabManager tabManager;
private final ImmutableList<Tab> tabs;
private final ImmutableList<TabButton> tabButtons;
private TabNavigationBar(int width, TabManager tabManager, Iterable<Tab> tabs) {
this.width = width;
this.tabManager = tabManager;
this.tabs = ImmutableList.copyOf(tabs);
this.layout.defaultCellSetting().alignHorizontallyCenter();
ImmutableList.Builder<TabButton> tabButtonsBuilder = ImmutableList.builder();
for (Tab tab : tabs) {
tabButtonsBuilder.add(this.layout.addChild(new TabButton(tabManager, tab, 0, 24)));
}
this.tabButtons = tabButtonsBuilder.build();
}
public static TabNavigationBar.Builder builder(TabManager tabManager, int width) {
return new TabNavigationBar.Builder(tabManager, width);
}
public void updateWidth(int width) {
this.width = width;
this.arrangeElements();
}
@Override
public boolean isMouseOver(double mouseX, double mouseY) {
return mouseX >= this.layout.getX()
&& mouseY >= this.layout.getY()
&& mouseX < this.layout.getX() + this.layout.getWidth()
&& mouseY < this.layout.getY() + this.layout.getHeight();
}
@Override
public void setFocused(boolean focused) {
super.setFocused(focused);
if (this.getFocused() != null) {
this.setFocused(null);
}
}
@Override
public void setFocused(@Nullable GuiEventListener focused) {
super.setFocused(focused);
if (focused instanceof TabButton button && button.isActive()) {
this.tabManager.setCurrentTab(button.tab(), true);
}
}
@Override
public @Nullable ComponentPath nextFocusPath(FocusNavigationEvent navigationEvent) {
if (!this.isFocused()) {
TabButton button = this.currentTabButton();
if (button != null) {
return ComponentPath.path(this, ComponentPath.leaf(button));
}
}
return navigationEvent instanceof FocusNavigationEvent.TabNavigation ? null : super.nextFocusPath(navigationEvent);
}
@Override
public List<? extends GuiEventListener> children() {
return this.tabButtons;
}
public List<Tab> getTabs() {
return this.tabs;
}
@Override
public NarratableEntry.NarrationPriority narrationPriority() {
return this.tabButtons.stream().map(AbstractWidget::narrationPriority).max(Comparator.naturalOrder()).orElse(NarratableEntry.NarrationPriority.NONE);
}
@Override
public void updateNarration(NarrationElementOutput output) {
Optional<TabButton> selected = this.tabButtons
.stream()
.filter(AbstractWidget::isHovered)
.findFirst()
.or(() -> Optional.ofNullable(this.currentTabButton()));
selected.ifPresent(button -> {
this.narrateListElementPosition(output.nest(), button);
button.updateNarration(output);
});
if (this.isFocused()) {
output.add(NarratedElementType.USAGE, USAGE_NARRATION);
}
}
protected void narrateListElementPosition(NarrationElementOutput output, TabButton widget) {
if (this.tabs.size() > 1) {
int index = this.tabButtons.indexOf(widget);
if (index != -1) {
output.add(NarratedElementType.POSITION, Component.translatable("narrator.position.tab", index + 1, this.tabs.size()));
}
}
}
@Override
public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
graphics.blit(
RenderPipelines.GUI_TEXTURED,
Screen.HEADER_SEPARATOR,
0,
this.layout.getY() + this.layout.getHeight() - 2,
0.0F,
0.0F,
this.tabButtons.get(0).getX(),
2,
32,
2
);
int afterLastTab = this.tabButtons.get(this.tabButtons.size() - 1).getRight();
graphics.blit(
RenderPipelines.GUI_TEXTURED,
Screen.HEADER_SEPARATOR,
afterLastTab,
this.layout.getY() + this.layout.getHeight() - 2,
0.0F,
0.0F,
this.width,
2,
32,
2
);
for (TabButton value : this.tabButtons) {
value.extractRenderState(graphics, mouseX, mouseY, a);
}
}
@Override
public ScreenRectangle getRectangle() {
return this.layout.getRectangle();
}
public void arrangeElements() {
int tabsWidth = Math.min(400, this.width) - 28;
int tabWidth = Mth.roundToward(tabsWidth / this.tabs.size(), 2);
for (TabButton button : this.tabButtons) {
button.setWidth(tabWidth);
}
this.layout.arrangeElements();
this.layout.setX(Mth.roundToward((this.width - tabsWidth) / 2, 2));
this.layout.setY(0);
}
public void selectTab(int index, boolean playSound) {
if (this.isFocused()) {
this.setFocused(this.tabButtons.get(index));
} else if (this.tabButtons.get(index).isActive()) {
this.tabManager.setCurrentTab(this.tabs.get(index), playSound);
}
}
public void setTabActiveState(int index, boolean active) {
if (index >= 0 && index < this.tabButtons.size()) {
this.tabButtons.get(index).active = active;
}
}
public void setTabTooltip(int index, @Nullable Tooltip hint) {
if (index >= 0 && index < this.tabButtons.size()) {
this.tabButtons.get(index).setTooltip(hint);
}
}
@Override
public boolean keyPressed(KeyEvent event) {
if (event.hasControlDownWithQuirk()) {
int tabIndex = this.getNextTabIndex(event);
if (tabIndex != -1) {
this.selectTab(Mth.clamp(tabIndex, 0, this.tabs.size() - 1), true);
return true;
}
}
return false;
}
private int getNextTabIndex(KeyEvent event) {
return this.getNextTabIndex(this.currentTabIndex(), event);
}
private int getNextTabIndex(int currentTab, KeyEvent event) {
int digit = event.getDigit();
if (digit != -1) {
return Math.floorMod(digit - 1, 10);
} else if (event.isCycleFocus() && currentTab != -1) {
int nextTabIndex = event.hasShiftDown() ? currentTab - 1 : currentTab + 1;
int index = Math.floorMod(nextTabIndex, this.tabs.size());
return this.tabButtons.get(index).active ? index : this.getNextTabIndex(index, event);
} else {
return -1;
}
}
private int currentTabIndex() {
Tab currentTab = this.tabManager.getCurrentTab();
int index = this.tabs.indexOf(currentTab);
return index != -1 ? index : -1;
}
private @Nullable TabButton currentTabButton() {
int index = this.currentTabIndex();
return index != -1 ? this.tabButtons.get(index) : null;
}
@OnlyIn(Dist.CLIENT)
public static class Builder {
private final int width;
private final TabManager tabManager;
private final List<Tab> tabs = new ArrayList<>();
private Builder(TabManager tabManager, int width) {
this.tabManager = tabManager;
this.width = width;
}
public TabNavigationBar.Builder addTabs(Tab... tabs) {
Collections.addAll(this.tabs, tabs);
return this;
}
public TabNavigationBar build() {
return new TabNavigationBar(this.width, this.tabManager, this.tabs);
}
}
}引用的其他类
-
- 引用位置:
方法调用/返回值 - 关联成员:
ComponentPath.leaf(), ComponentPath.path()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
TabButton()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
LinearLayout.horizontal()
- 引用位置:
-
- 引用位置:
实现/返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Component.translatable()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.clamp(), Mth.roundToward()
- 引用位置: