Skip to content

GUI(一)

USS-Shenzhou edited this page Jan 9, 2023 · 6 revisions

介绍

目前,T88的GUI部分主要特点是:仅客户端、非Inventory/Container、尽量贴近原版风格、带有一些Swing风格。

在T88中,TWidget是最基本的接口,所有组件都实现此接口;widget包中包含基本组件,advanced包中包含一些略复杂的组件,combine包中包含一些由组件组合而成的组件。

目前有EditBoxFocusedEventTWidgetContentUpdatedEvent两个事件,均位于Forge总线。

快速Q&A

Q:我可以将原版或者第三方的GUI类转移到T88吗?

A:可以。在大多数情况下,只需要实现TWidget接口即可。


Q:我要如何新建自己的组件?

A:继承TPanel即可。

在构造函数中使用add(TWidget child)方法以添加子组件。继承于TWidget的子组件会自动地被渲染(调用其render方法),不需要您在render(PoseStack...)中手动指出。

和Swing的LayoutManager类似,在layout()方法中使用setBounds(int x, int y, int width, int height)对子组件以相对坐标设置位置和大小。

如果要使用tick方法,请使用tickT()方法。T88中与原版重名的方法均在后面加T

请注意,在正常情况下,重写layout()tickT()render(PoseStack...)之后,你应该在方法末尾调用超类的相应方法。即

@Override
public void layout() {
child.setBounds...
...
super.layout();
}

Q:懒得写触发,有什么方便的办法快捷地可以在游戏中查看我写的Screen吗?

A:在启动时指定propertyt88.test_screen_override的值为你所写的Screen的名称,进入游戏后按ctrl+T,T88会简单地使用Class.forName来查找你的Screen并尝试实例化一个,让MC显示它。

结构图

这是一张T88的GUI类结构图,在新标签页打开以放大查看。不保证即时性和完整性。

image

以下是基础组件的介绍。

TWidget

TWidget是整个T88的基础。

由于重名的缘故,对变量visible的getter和setter为isVisibleT()setVisibleT(boolean visible)

void setBounds(int x, int y, int width, int height)

指定组件的位置和大小。使用相对位置,即(0,0)表示父类的最左上角。

void setAbsBounds(int x, int y, int width, int height)

指定组件的位置和大小。使用绝对位置,即(0,0)表示窗口(Screen)的最左上角。

Vec2i getPreferredSize()

返回组件自我建议的大小。以按钮为例,其返回(52,20)表示一个长度为52,但高度为20的黄金比例大小。

没有指定建议的大小时应返回当前大小。

default boolean isInRange(double pMouseX, double pMouseY, double xPadding, double yPadding)

判断输入的鼠标位置是否在本组件的范围内。padding为向外延伸的容差值。

default void onFinalClose()

在Screen关闭时调用,可以用于取消注册等。

default @Nullable <T extends TWidget> T getParentInstanceOf(Class<T> c)

返回指定类型的父组件。若找不到则返回null

default double getParentScrollAmountIfExist()

返回父滚动面板(TScrollPanel)的滚动值。若无父滚动面板则返回0。

此返回值在向上滚动(向下滚滚轮)时为正,故若要将此用于鼠标判定修正,则取此数;若要用于渲染修正,则取相反数。

TComponent

TComponentGuiComponentTWidget的基本实现。

public void add(TWidget child)
public void remove(TWidget tWidget)

将组件添加到子组件表(或移除)。在本组件的layout()tickT()render(PoseStack...)等方法执行完成之后,子组件的对应方法将被相应地调用。

public void setBorder(Border border)

设置一个边界框。通常为外边框。通常用于开发环境调试。

public Border(int color, int thickness)

0xaarrggbb格式指定边界框的颜色,指定边界框的厚度。

public void setBackground(int background)

0xaarrggbb格式指定背景颜色。

public void setForeground(int foreground)

0xaarrggbb格式指定前景颜色。前景颜色在此处并无实际作用。

TPanel

TComponent的封装。目前没有特别的功能。通常作为一个组件容器使用。

TScrollPanel

支持滚动以在纵向容纳更多内容的TPanel。不支持横向滚动。

为子组件指定位置时正常填写即可(即使数值超出了屏幕大小),滚动条会自动地被启用。

public int getUsableWidth()

返回可用宽度。当您在为子组件进行布局时应使用此方法,而不是this.getWidth()

public double getScrollAmount()

获取滚动值。向上滚动(向下滚滚轮)时为正。

public void addScrollAmount(double deltaScroll)

指定滚动增量。向上滚动(向下滚滚轮)时为负。

public int getScrollbarGap()
public void setScrollbarGap(int scrollbarGap)

返回(指定)滚动条与可用区域的间隙大小。默认为0。

TLabel

用于显示一行文字。

public TLabel(Component s, int foreground)

指定要显示的文本,以0xaarrggbb格式指定文本的颜色。

public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment)

设置文本的对齐方式。提供左对齐、居中和右对齐。

public void setFontSize(int size)

指定文本大小。默认大小为7。

TTitledComponent<T extends TWidget>

这是一个组合组件,用于给某个组件添加一个标题。

提供的实现有TTitledButtonTTitledCycleButton\<E>TTitledEditBoxTTitledSelectList\<E>TTitledSimpleConstrainedEditBoxTTitledSuggestedEditBox

子组件的位置在defaultLayout()中被自动地设置。若要手动指定其位置,请重写defaultLayout()(而不是layout()),不需要在最后调用超类的此方法。

标题默认为左对齐。

就像这句话相对于下面这个引用框一样。

public int getGap()
public void setGap(int gap)

返回(指定)标题与组件的间隙大小。默认为0。

public int getLabelHeight()
public void setLabelHeight(int labelHeight)

返回(指定)标题的高度。默认为12。

TSlider

滑动条。原版SliderButton的T88封装。

实现了接口TResponder<T>标志着这个类有响应器。其中的T通常是组件自己或自己的值,在此处是滑动条的浮点数值。

public TSlider(double pMinValue, double pMaxValue, float pSteps, Component tipText)

指定最小值,指定最大值,指定步进,指定要显示的文本。

由于缩放的关系,步进通常不起实际意义,只需要填入一个较小的值。如当范围为0-1时,填入0.01即可。

public void setValue(double value)
public double getValue()

指定(返回)滑动条的值。响应器会在指定值后被触发。

public void setValueWithoutRespond(double value)

在不触发响应器的情况下指定滑动条的值。适用于滑动条和其他组件相互进行更改的情况,避免无限相互调用。

TButton

按钮。原版Button的T88封装。

public TButton(Component pMessage, OnPress pOnPress, OnTooltip pOnTooltip)

指定按钮上要显示的文本,指定被按下时的动作,pOnTooltip暂时不起实际作用。

TCycleButton<E>

循环式按钮,在可选元素中循环切换。继承于TButton,而非继承于原版CycleButton

可选元素是内部类Entry,含有实际内容E content和响应器Consumer<TCycleButton<E>> onSwitched

建议泛型E实现接口ToTranslatableString,以指定语言文件中的键值。未实现的E将直接调用toString()

public void addElement(E e)

添加可选元素。

public void removeElement(E e)

移除可选元素。

Entryequals方法经过重写,以实际内容E content为准,而不论响应器的内容。

public int getSelectedIndex()

返回当前被选中的元素序号。

public LinkedList<Entry> getValues()

返回所有可选元素。

public @Nullable Entry getSelected()

返回被选中的元素。当无可选元素是返回null

public void select(int index) throws IndexOutOfBoundsException

指定选中对应序号的元素。

被选中的元素会触发其响应器Consumer<TCycleButton<E>> onSwitched

发出事件TWidgetContentUpdatedEvent

public void select(E content)

指定选中含有填入内容的元素。

TSelectList<E>

选择表,原版ObjectSelectionList<E extends ObjectSelectionList.Entry<E>>的T88封装。

可选元素是内部类Entry,含有实际内容E content和响应器Consumer<TSelectList<E>> onSwitched,以及可以单独指定的前景色Integer specialForeground

建议泛型E实现接口ToTranslatableString,以指定语言文件中的键值。未实现的将直接调用toString()

public TSelectList(int pItemHeight, int scrollbarGap)

指定每栏的高度,指定主要区域和滚动条的间隙大小。

对可选元素的操作与TCycleButton<E>类似。

被选中的元素会触发其响应器Consumer<TSelectList<E>> onSwitched

但不会发出事件TWidgetContentUpdatedEvent

public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment)

指定元素显示文字的对齐方式。默认是居中。

TEditBox

输入框,原版EditBox的T88封装。实现了接口TResponder<String>

在被聚焦时发出事件EditBoxFocusedEvent,由其他输入框接受并取消自己的聚焦状态。防止多个输入框同时显示为聚焦状态。

在输入内容时发出事件TWidgetContentUpdatedEvent

public TEditBox(Component tipText)

不起实际作用。

@Override
public void setEditable(boolean pEnabled)

指定是否可以被编辑。若指定为不可编辑时没有输入内容,则显示不可用

public boolean isEditable()

返回是否可以被编辑。是对Mixin类AccessorProxy中对应方法的方便封装。

TImage

展示一张图片。构造函数中填入图片路径即可。

public void setImageFit(ImageFit imageFit)

指定图片展示时的契合方式。提供FILL填充、FIT适应、STRETCH拉伸和TILE平铺。参考桌面壁纸设置方式。默认为FILL填充。

public void setScale(float scale)

指定图片的大小缩放。仅推荐在TILE模式下使用。默认值为1。