- Версия(и) Minecraft
- 1.12
Давно уже была мысль сделать что-то подобное. Во многих проектах приходится делать одно и то же - так почему бы не обобщить GUI-компоненты под единым API, подумал я... И сделал.
GuiLib - это движок для создания полноценных внутриигровых интерфейсов(уровня самостоятельных программ). Он предоставляет API и основные его реализации. Больше никакого GL-кода в интерфейсах. ООПшно и сердито.
Основные возможности:

Сборка библиотеки из исходников выполняется командой
P.S. Проект GuiLib находится в стадии альфы(в основном работает, но не без багов). Буду рад любым советам, а тем более помощи.
GuiLib - это движок для создания полноценных внутриигровых интерфейсов(уровня самостоятельных программ). Он предоставляет API и основные его реализации. Больше никакого GL-кода в интерфейсах. ООПшно и сердито.
Основные возможности:
- Единое API графических компонентов
- Модульная сборка всех компонентов как главная идеология библиотеки. Чёткое разделение ответственности за логические части функционирования интерфейса. За счёт этого сложные компоненты можно собирать из более мелких. Так, например, панель
GPanel
- это инструмент композиции, которому можно установить любой обработчик прокрутки - графический компонент, обрабатывающий ввод мыши и рисующий скроллбары, если нужно. Такой подход улучшает читаемость кода и позволяет сконцентрироваться на решении маленькой задачи в каждый конкретный момент времени - Удобное создание каждого компонента через фабрики. Код максимально короткий и читаемый
- Полная абстракция рисования. Гарантируется, что криво написанный рендер одного компонента не может сломать работу другого. Кроме того, ваше рисование не зависит от координат компонента в контейнере! Можно считать, что функция
draw
получает систему координат, связанную с вашим компонентом. Не важно, что вы натворите в своей функции рисования - матрица преобразований на выходе из неё будет сброшена - Интегрированная обрезка кадра, используя
glScissor
. Все компоненты по умолчанию обрезаются до своей ширины и высоты, заявленной в реализации API - Инструменты компоновки(композиции). Они же контейнеры. Это компоненты с одной целью - содержать в себе и определённым образом располагать другие компоненты
- Иерархический 'проброс' в эти компоненты основных событий ввода - мышка нажата, отпущена, нажата клавиша на клавиатуре. Тем же образом передаются события наведения(hover), изменения размеров окна(resize), проверки обновлений и обновления(update) и прочее. Ну и, конечно, отрисовки компонента
- Слушатели(Listener). Можно реализовать в своем компоненте интерфейс
IListener
и управлять своим состоянием в зависимости от состояния цели. Да, прямо у себя, не залезая в основной контейнер - Продвинутая работа с элементами интерфейса. Класс
StyleMap
представляет из себя то, что может нарисовать кнопку, скроллбар, фон, иконку любого размера! Кроме того, это позволяет делать несколько стилей графических интерфейсов, меняя всего одну текстуру в ресурсах - Платформонезависимый код. Можно легко и быстро реализовать API адаптеров под абсолютно любую платформу, при этом основной код библиотеки трогать не придётся
Сборка библиотеки из исходников выполняется командой
shadowJar
из модуля реализации адаптеров(в стандартной поставке это forge112
).Итак. Для начала нам потребуется корневой контейнер - в библиотеке предусмотрены расширения для
Теперь, вероятно, мы хотим туда что-то добавить. Самое простое, что мы можем, когда у нас ничего нет - это добавить надпись. Так и сделаем. За создание компонентов отвечает класс
Просто, не правда ли? Вот и я так думаю. Все компоненты собираются похожим образом. Сделаем что-то посложнее, например, ссылку.
Под конец построим сложный компонент с множеством настраиваемых параметров. Думаю, уже можно не комментировать каждую строчку:
Эти и другие примеры размещены в классе
GuiScreen
, GuiContainer
и Gui
. Унаследуйте интерфейс от одного из них, их работа с точки зрения библиотеки абсолютно одинакова. Я возьму GuiScreen, точнее, его Extended версию:
Java:
public class GuiTest extends ExtendedGuiScreen {
@Override
public void init() {
// здесь мы будем создавать нашу структуру компонентов
}
}
Graphics
. Добавим в init()
:
Java:
GLabel label = Graphics.label() // создаём надпись
.text("Hello, world!") // устанавливаем текст
.placeAt(50, 50) // размещаем на координатах (50, 50)
.build(); // собираем компонент
this.add(label); // добавляем собранный компонент в корневой контейнер
Java:
GLink link = Graphics.link() // создаём ссылку
.text("GuiLib original source") // устанавливаем текст
.url("https://github.com/StannisMod/guilib") // ссылку
.color(0xffffff, 0x121212) // активный и пассивный цвет
.scale(2.0F) // увеличение
.placeAt(250, 200) // размещаем на координатах (250, 200)
.build(); // собираем компонент
this.add(link); // добавляем собранный компонент в корневой контейнер
Java:
this.add(100, Graphics.button() // поставим глубину 100, чтобы кнопка была поверх всего остального
.label(Graphics.label().text("Primary text", 0xffffff).scale(2.0F).setCentered().build())
.action(button -> {
if (button.getLabel().getText().startsWith("P")) {
button.getLabel().setText("SecondaryText");
} else {
button.getLabel().setText("PrimaryText");
}
})
.size(150, 60)
.placeAt(800, 400)
.build());
ru.quarter.gui.lib.forge112.GuiTest
P.S. Проект GuiLib находится в стадии альфы(в основном работает, но не без багов). Буду рад любым советам, а тем более помощи.