Stupid-GUI

shrug228

Активный
Автор темы
212
76
Stupid-GUI(SGUI) | v2


Дисклеймер: Представляю, сколько будет хейта в мою сторону в комментариях) В общем, здесь я немного расскажу про свое творение под названием SGUI. Работает на рендере, огромном количестве костылей и говнокода. Особенность в том, что гемороя из-за моего гениального проектирования будет максимально много. Разработчику предстоит познать все прелести ООП в Lua, в связи с чем советую с ними ознакомиться по этой статье, например. Но сначала дочитайте пост до конца. ;) Кстати, одновременно использовать приватные поля у классов и наследование нельзя(опять же по этой статье если действовать).


Для начала подключим саму библиотеку:
Lua:
require("lib.sgui")
Начнем с самого основного - создадим окно. Для этого достаточно строчки кода для создания окна и еще одной для его отображения:

Lua:
win= Window:new('Window')
while true do
    win:draw()
end
Почему же ничего не произошло? Дело в том, что изначально наше окно закрыто. За отображение окна отвечает поле win.state, в котором нам соответственно нужно поставить значение true. Результат:
E5zQf9q.png
Вообще у всех классов в SGUI довольно большое количество параметров если чуть подразобраться. Но для упрощения работы я проставил каждому дефолтное значение, так что аргументы можно не указывать вообще(или везде вписать nil). Другой вопрос, что тогда не будет даже заголовка окна. Ладно, вернемся к нашим баранам. Я лично предпочитаю использовать заодно вот такой шаблон для команд открытия/закрытия окон. Можете взять себе на вооружение)
Lua:
    sampRegisterChatCommand(string.sub(thisScript().name, 1, string.len(thisScript().name) - 4), function () win.state = not win.state end)
    -- мы берем название скрипта и отрезаем кусок от 1 до 4 до с конца символа. это будет работать, если у вы не скомпилировали файл(не получили .luac)
    -- если вы предварительно задали название скрипта через script_name(), то можно ничего не отрезать и использовать просто thisScript().name
Окно можно стилизовать, как вашей душе угодно. Стиль элемента хранится соответственно в поле obj.style и является таблицей(aka table). В качестве примера ниже разберем стандартный стиль - DEFAULT_STYLE:
Lua:
local DEFAULT_STYLE = {
    bg = 0x99000000, -- фон окна
    top = 0xff000000, -- шапка окна
    color = 0xffc0c0c0, -- фон кнопки
    press = 0xff7b68ee, -- цвет кнопки при нажати и второстепенный цвет некоторых виджетов
    fcolor = 0xffffffff, -- цвет шрифта
    close = 0xffff6347, -- цвет кнопки закрытия
    font = renderCreateFont("Trebuchet MS", 16, font_flag.SHADIW + font_flag.BORDER) -- шрифт
}
Ладно, перейдем к функционалу. Создадим кнопку, это можно сделать несколькими способами.
Lua:
-- 1
btn = Button:new('1') -- создаем кнопку
btn:bind(function () -- задаем функцию, которая сработает при нажатии
    printStringNow('pressed', 1000)
end)
win:tieElement(btn)   -- передаем отрисовщику окна(расположит автоматически)

-- 2
win:tieElement(Button:new('2', nil, nil, 'right')) -- создаем кнопку и передаем отрисовщику окна(параметр 'right' означает, что кнопка будет справа от предыдущего элемента. иначе указывайте nil)
win:getElement(2):bind(function () -- также задаем функцию, которая сработает при нажатии
    printStringNow('pressed', 1000)
end)

-- 3
btn2 = Button:new('3') -- создаем еще одну кнопку
btn2.func = function () -- задаем функцию, но уже не через метод, а напрямую
    printStringNow('pressed', 1000)
end

while true do
    win:draw()
    if win.state then -- проверяем, что окно открыто
        btn2:draw(win.pos.x + win.size.x / 2, win.pos.y + win.size.y / 2) -- эта кнопка не подключена к отрисовщику окна, так что отрисовываем самостоятельно
    end
end
Я лично бы предпочел воспользоваться 1-ым, но тут уже, как хотите. Задачу свою кнопка выполнит в любом случае. Результат всех этих манипуляций:
LI77stJ.png
Ну и на последок взглянем на одну по моему скромному мнению очень удобную штуку.

Lua:
dlg = Dialog:new('Какой-то вопрос.', {'Ответ 1', 'Ответ 2', 'Ответ 3', 'И т.д.'}) -- ответы отображаются в обратном порядке, их количество может быть любым
-- также по умолчанию включен автоперенос текста(Dialog.wrapping). Не нравится - поставьте на false и переносите сами(\n)
dlg.win.state = true -- класс Dialog лишь оболочка, он просто приводит в нужный вам вид окно. само окно - Dialog.win

while true do
    dlg:draw() -- но при этом отрисовка происходит через собственный метод класса Dialog
end
Результат:
1QAB2ka.png


Установка: закинуть sgui.lua в moonloader/lib. Требования: moonloader 0.26. Предназначено для SAMP-а, в одиночке скорее всего работать не будет, но я не проверял.
Если вас заинтересовала эта библиотека - не бойтесь залезть в исходники, там все относительно понятно. И много новых свойств объектов узнаете)
 

Вложения

  • sgui.lua
    13.4 KB · Просмотры: 49
Последнее редактирование:

ARMOR

Waitin' on another black summer to end
Модератор
5,044
7,234
Всё бы ничего, но зачем?
 

shrug228

Активный
Автор темы
212
76
чем он лучше, чем отличается, или какие преимущества от imgui/mimgui?
Отличие упомянуто в теме много раз - ООП. Преимуществ нагреб несколько, хотя они немного сомнительные:
1) Шире возможности в плане изменения библиотеки. Не нравится отрисовка кнопки - пожалуйста, меняй, никто не запрещает. Это следствие ООП. ImGui же написан на плюсах, как я знаю, так что и отредактировать отрисовку кнопки, например, не вариант.
2) Проще стилизовать окно. Стиль представляет из себя просто массив(таблицу aka table). Элементы можно располагать, как душе угодно. Да, в imgui тоже есть некоторые возможности, но тут их больше, так как располагаешь все вручную.
3) Скорее всего перейти на эту штуку людям, которые до селе не работали с imgui/mimgui, но имели опыт работы с обычным GUI(Qt, GTK и т.д.) будет проще.
Всё бы ничего, но зачем?
По приколу, если честно. Я вообще не думал, что развивать буду эту штуку после выкладывания. Но лайков накидали - придется продолжать)
 
Последнее редактирование:
  • Bug
Реакции: etereon и kin4stat

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,750
4,857
2) Проще стилизовать окно. Стиль представляет из себя просто массив(таблицу aka table).
Ты не представляешь, в ImGui это структура, которую также легко менять, и причем работает это по принципу стека
Элементы можно располагать, как душе угодно.
Ты не представляешь, но в ImGui тоже
Это следствие ООП.
спс поржал
 
  • Нравится
Реакции: etereon

shrug228

Активный
Автор темы
212
76
Обращайся, я тупой)
Ты не представляешь, в ImGui это структура, которую также легко менять, и причем работает это по принципу стека
Взгляни на стили imgui и на их размеры. Согласись, накидать массив намного проще и гемороя поменьше будет)
Ты не представляешь, но в ImGui тоже
Хочешь ты того или нет, но при ручном расположении по координатам все будет можно расположить интереснее, только нужна фантазия.
 

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,750
4,857
Взгляни на стили imgui и на их размеры.
Ты немного путаешь.
Хочешь ты того или нет, но при ручном расположении по координатам все будет можно расположить интереснее, только нужна фантазия.
Красивые меню на имгуи так и делаются
 

The Spark

frontend
Проверенный
727
741
SetCursorPos()

Я не выкупаю или ты действительно думаешь что m/imgui дубовый и там не где развернуться?
А как же стили, флаги, свой рендер, селекторы, гистограммы и ещё много всего? Глянь imgui demo.
Строить интерфейс всегда удобнее через стек, но и указать абсолютную позицию никто не запрещает. Создаёшь окошко без тайтла и перед тобой открываются огромные возможности рендера gui. Зайди в полезные сниппеты, смотри какую красоту люди делают.
Сейчас sgui не лучше dxut диалогов (там кста тоже все через x y).
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,562
Lua:
if self.pos ~= {x = self.selfpos.x + parent.pos.x, y = self.selfpos.y + parent.pos.y} then -- 65 строка
эта проверка всегда будет срабатывать т.к. таблицы сравниваются не по их элементам, а скорее всего по адресу
1640692762418.png