Moon ImGui — Dear ImGui for MoonLoader

29072770-aef614e2-7c7b-11e7-8861-212c2c416439.png


Это ImGui - самый функциональный и одновременно самый простой GUI-фреймворк из всех, что мне известны.
И теперь каждый из вас сможет использовать его в своих Lua скриптах для MoonLoader.

Представляю вам Moon ImGui - Lua биндинг ImGui для MoonLoader. Он включает все основные возможности фреймворка, а API максимально приближен к оригинальному по мере возможного.
Тут не будут подробно рассматриваться возможности и особенности ImGui, в этой теме будет рассказано и показано как использовать Moon ImGui в Lua. За информацией по самому ImGui сюда:

Начнём с самого элементарного:
Lua:
local imgui = require 'imgui' -- загружаем библиотеку

-- в этой функции осуществляется вся работа с ImGui
-- она вызывается каждый кадр, но только если imgui.Process равен true
function imgui.OnDrawFrame()
  imgui.Begin('My window') -- новое окно с заголовком 'My window'
  imgui.Text('Hello world') -- простой текст внутри этого окна
  imgui.End() -- конец окна
end

function main()
  imgui.Process = true -- ImGui будет обрабатываться, пока imgui.Process равен true
  -- в этом примере мы просто активируем ImGui сразу же после загрузки игры
end
Результат:
upload_2017-11-25_18-29-2.png


Это работает, но что-то не впечатляет, согласитесь. Окно изначально маленькое, показывается сразу при старте и его нельзя закрыть.
Сделаем его побольше, добавим активацию и какое-нибудь действие:
Lua:
local imgui = require 'imgui'
local key = require 'vkeys'

-- одно из основных отличий от оригинального апи
-- все переменные, значения которых записываются в ImGui по указателю, могут использоваться только через специальные типы
local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
  if main_window_state.v then -- чтение и запись значения такой переменной осуществляется через поле v (или Value)
    imgui.SetNextWindowSize(imgui.ImVec2(150, 200), imgui.Cond.FirstUseEver) -- меняем размер
    -- но для передачи значения по указателю - обязательно напрямую
    -- тут main_window_state передаётся функции imgui.Begin, чтобы можно было отследить закрытие окна нажатием на крестик
    imgui.Begin('My window', main_window_state)
    imgui.Text('Hello world')
    if imgui.Button('Press me') then -- а вот и кнопка с действием
      -- условие будет выполнено при нажатии на неё
      printStringNow('Button pressed!', 1000)
    end
    imgui.End()
  end
end

function main()
  while true do
    wait(0)
    if wasKeyPressed(key.VK_X) then -- активация по нажатию клавиши X
        main_window_state.v = not main_window_state.v -- переключаем статус активности окна, не забываем про .v
    end
    imgui.Process = main_window_state.v -- теперь значение imgui.Process всегда будет задаваться в зависимости от активности основного окна
  end
end
Теперь окно выглядит так и его можно скрыть:
upload_2017-11-25_18-29-17.png


В коде была использована переменная типа ImBool - это один из новых типов, добавленных в Moon ImGui. Такой подход неизбежен, поскольку в луа невозможна передача базовых типов по ссылке. Это не единственное изменение, есть и другие, вам потребуется о них знать. Вот их полный список:

Разница между C++ API и Lua API
ОписаниеВ C++В Lua
Все функции из пространства имён ImGui, как и все типы, и все перечисления находятся в таблице, возвращаемой модулемImGui::Text("text");
ImVec2(0.1f, 2.3f);
imgui.Text("text");
imgui.ImVec2(0.1, 2.3);
Названия перечислений (enum) и их значений лишились префиксов и символа "_" в концеImGuiWindowFlags_NoTitleBarimgui.WindowFlags.NoTitleBar
Значения базовых типов, которые в ImGui записываются по указателю, должны быть использованы через специальные типы: ImBool для bool, ImFloat для float, ImInt для int и unsigned int, ImFloat2-4 для float[2-4], ImInt2-4 для int[2-4]static bool win = false; ImGui::Begin("window", &win);
win = false;
local win = imgui.ImBool(false) imgui.Begin("window", win)
win.v = false
Функции с переменным количеством аргументов для форматирования текста не поддерживают форматирование, используйте string.formatImGui::Text("hey, %s", name)imgui.Text(string.format('hey, %s', name))
Функции InputText и InputTextMultiline принимают ImBuffer вместо char* buf + size_t buf_sizechar buf[256]{};
ImGui::InputText('input', buf, sizeof(buf))
local buf = imgui.ImBuffer(256);
imgui.InputText('input', buf)
Динамические массивы в виде массива указателей + количество элементов заменены таблицамиconst char* items[] = {"1", "2", "3"}; ImGui::ListBox("list", &lb_cur, items, 3)imgui.ListBox('list', lb_cur, {'1', '2', '3'})
Функции с аргументами const char* str_start, const char* str_end, идущими подряд, принимают обычную строкуImGui::TextUnformatted(some_str, some_str + 24)imgui.TextUnformatted(some_str)
Все функции, принимающие калбэк + user_data, принимают ImCallbackvoid swszCb(ImGuiSizeConstraintCallbackData*) {};
ImGui::SetNextWindowSizeConstraints(size_min, size_max, &swszCb, (void*)&my_data)
local swszCb = imgui.ImCallback(function(data) end)
imgui.SetNextWindowSizeConstraints(size_min, size_max, swszCb)
ImFont::CalcTextSizeA,
ImFontAtlas::CustomRect::CalcCustomRectUV,
ImFontAtlas::GetTexDataAsRGBA32,
ImFontAtlas::GetTexDataAsAlpha8,
ImFontAtlas::GlyphRangesBuilder::BuildRanges,
ImGui::ColorConvertRGBtoHSV и
ImGui::ColorConvertHSVtoRGB
возвращают значения вместо изменения по ссылке
float r, g, b;
ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b);
local r, g, b = imgui.ColorConvertHSVtoRGB(h, s, v)
ImGuiIO::IniFilename и ImGuiIO::LogFilename принимают ImBuffer вместо указателя на строкуconst char ini_path[] = "my/path.ini";
ImGui::GetIO().IniFilename = ini_path;
local ini_path = imgui.ImBuffer('my/path.ini')
imgui.GetIO().IniFilename = ini_path
Изменение ImGuiTextEditCallbackData::Buf автоматически обновляет длину и задаёт значение BufDirtys.copy(data.Buf, data.BufSize);
data.BufTextLen = s.length();
data.BufDirty = true;
data.Buf = 'text'

Остальные изменения
  • Добавлено несколько дополнительных функций
    • ImColor::ToU32 - преобразование ImColor в целое
    • ImGui::GetStyleColorU32 вместо ImGui::GetColorU32 для цвета стиля
    • ImGui::PlotLinesEx вместо callback-варианта PlotLines
    • ImGui::PlotHistogramEx вместо callback-варианта PlotHistogram
    • ImDrawList::AddTextEx вместо AddText с дополнительными аргументами
  • Отсутствуют функции
    • Функции, принимающие и возвращающие void*-идентификаторы (например, PushID(void*) и GetID(void*))
    • Функции с va_list-форматированием текста (например, TextV)
Теперь, зная всё это, вы уже можете начать работать с Moon ImGui. За списком функций ImGui и примерами на C++ обращайтесь на официальную страницу.

Но это ещё не всё. Вся работа с текстом в ImGui основана на UTF-8, т.е. текст не ограничен лишь стандартным набором символов. Но т.к. GTA, SAMP и MoonLoader не поддерживают юникод, кодировки необходимо конвертировать.

Работа с другими языками на примере русского
В MoonLoader v.025 были добавлены библиотеки lua-iconv и encoding, они призваны помочь в работе с разными кодировками текста.
Следующий пример показывает как использовать текст на русском в ImGui:
Скрипт должен быть сохранён в кодировке Windows-1251
Lua:
local imgui = require 'imgui'
local encoding = require 'encoding' -- загружаем библиотеку
encoding.default = 'CP1251' -- указываем кодировку по умолчанию, она должна совпадать с кодировкой файла. CP1251 - это Windows-1251
u8 = encoding.UTF8 -- и создаём короткий псевдоним для кодировщика UTF-8

local test_text_buffer = imgui.ImBuffer(256)
function imgui.OnDrawFrame()
  imgui.Begin(u8'Основное окно') -- обратите внимание на u8 перед текстом, это и есть преобразование кодировки
  if imgui.InputText(u8'Вводить текст сюда', test_text_buffer) then -- условие будет срабатывать при изменении текста
    -- здесь первая строка передаётся по-обычному, без u8
    -- но введённый текст при выводе преобразуется обратно из UTF-8 в кодировку по умолчанию, т.е. в Windows-1251
    print('Введённый текст:', u8:decode(test_text_buffer.v)) -- при работе с ImBuffer тоже не забывайте о .v
  end
  imgui.Text(u8'Введённый текст: ' .. test_text_buffer.v) -- но тут обратное преобразование введённого текста не требуется, т.к. текст буфера и так в UTF-8
  imgui.Text(u8(string.format('Текущая дата: %s', os.date()))) -- u8 - это функция, её можно использовать и с неконстантными строками
  imgui.End()
end

function main()
  imgui.Process = true
end
Результат:
upload_2017-11-25_18-29-37.png


Не так уж и сложно, верно? Текст, передаваемый ImGui - кодируем, текст, получаемый из ImGui - декодируем. Если в вашем скрипте много текста на русском для ImGui, но мало текста, выводимого через MoonLoader (в лог или чат SA:MP, к примеру), то можно сделать наоборот - сохранить скрипт в кодировке UTF-8 и не кодировать текст, передаваемый ImGui, а вместо этого кодировать текст при работе с функциями мунлоадера.

Остальные особенности
В Moon ImGui есть несколько дополнительных возможностей. В частности, они реализуют взаимодействие с игрой и управление интерфейсом.
Код:
Параметры
imgui.BeforeDrawFrame = nil  -  опциональный калбэк. Если он задан, будет вызываться каждый кадр перед OnDrawFrame и NewFrame самого ImGui. Его можно использовать для загрузки шрифтов и текстур (будьте осторожны, он вызывается каждый кадр)
imgui.OnDrawFrame = nil  -  основной калбэк для рендера, о нём вы уже знаете
imgui.Process = false  -  только если задано true, имгуи будет обрабатываться и выводиться
imgui.RenderInMenu = false  -  показывать интерфейс в меню паузы, по умолчанию отключено
imgui.ShowCursor = true  -  показывать курсор, по умолчанию включен. Отключение может пригодиться, если нужно рисовать только какой-то оверлей без взаимодействия с ним
imgui.LockPlayer = false  -  отключить управление игроком, пока ImGui активен. Если не задано, то управление игроком будет отключаться только когда ImGui требуется обработать ввод с клавиатуры

Функции
после загрузки новых шрифтов и обязательно вне OnDrawFrame
function imgui.CreateTextureFromFile(path)  -  загрузить текстуру из файла. Возвращает загруженную текстуру или nil в случае неудачи
function imgui.CreateTextureFromMemory(address, size)  -  загрузить текстуру из изображения, хранящегося по указанному адресу в памяти. Возвращает загруженную текстуру или nil в случае неудачи
function imgui.GetTextureFromAddress(address)  -  получить ImGui-совместимую текстуру по адресу памяти
function imgui.ReleaseTexture(texture)  -  выгрузить текстуру, загруженную с помощью CreateTextureFromFile или CreateTextureFromMemory\
function imgui.RebuildFonts()  -  пересобрать внутреннюю текстуру шрифтов. Необходимо использовать
function imgui.SwitchContext()  -  переключить ImGui-контекст на принадлежащий скрипту. В BeforeDrawFrame и OnDrawFrame контекст переключается автоматически, так что в них эту функцию использовать нет нужды.

На этом всё. Во вложениях есть пример с демонстрацией использования всех этих фич, рекомендую посмотреть код и пощупать его в игре. Вот скриншот:

upload_2017-11-25_18-28-12.png

Полезные штуки для разработчиков
FontAwesome 4: https://blast.hk/threads/19292/post-168990
FontAwesome 5: https://blast.hk/threads/19292/post-335148
ImGui Pie: https://blast.hk/threads/19648/post-226145
Внутриигровая песочница: https://blast.hk/threads/19292/post-219453
ImGui Custom (хоткеи и ещё чет): https://blast.hk/threads/22080/
Global notification: https://blast.hk/threads/21619/
Стили:
https://blast.hk/threads/19292/post-260462

Ссылки
Скачать Moon ImGui (Download)
Установка:
распаковать содержимое архива в корневую папку игры.
Требуется MoonLoader v.026 или выше
Официальная страница ImGui
Пример на C++ с применением большинства возможностей (imgui_demo.cpp)
Все функции ImGui (imgui.h. Список поддерживаемых также есть в imgui.lua)
 

Вложения

  • moon imgui demo.lua
    9.2 KB · Просмотры: 122,268
Последнее редактирование:

ak4k1y

Участник
71
7
Подскажите пожалуйста как загрузить картинку в имгуи?
Вот такой код почему-то не работает. Картинка просто не появляется.
(не знаю какие аргументы что значат, но строчку я взял из Imgui Scoreboard с функцией добавить картинку на задний фон)
Lua:
------------------------------------------------------
local background = nil
---------------------------------------------------------
if doesFileExist("C:\\Games\\GTA San Andreas(osn)\\moonloader\\resource\\wind.png") then
    background = imgui.CreateTextureFromFile("C:\\Games\\GTA San Andreas(osn)\\moonloader\\resource\\wind.png")
else
    background = nil
end
---------------------------------------------
if imgui.Button(u8'123', imgui.ImVec2(70, 0)) then
    ima.v = not ima.v
end
if ima.v and background then
    imgui.Separator()
    imgui.Image(background, imgui.ImVec2(0 , 200), imgui.ImVec2(0, 0), imgui.ImVec2(1, 1), imgui.ImColor(155, 155, 155, 155):GetVec4())
end
----------------------------------------------

В целом код рабочий, даже нет никаких ошибок и в логе ничего нет.
Тут должна быть картинка, но появляется пустое поле с указанным размером
1586628217537.png
 

vodya

Участник
19
33
Как сделать так, чтобы при нажатии кнопки "Создать новую радиостанцию", я попадал в меню с кнопками "Ссылка на видеоролик, либо прямую трансляцию" и "Удалить существующую радиостанцию"? День мучаюсь, не могу найти. Подкину репы
Lua:
function imgui.OnDrawFrame()
    imgui.Begin(u8"[Онлайн радио v0.9]", main_window_state)
    if imgui.Button(u8"Создать новую радиостанцию") then
        imgui.Button(u8"Ссылка на видеоролик, либо прямую трансляцию")
        imgui.Button(u8"Название радиостанции, отображаемое в игре")
    end
    imgui.Button(u8"Настройки существующих радиостанций")
    imgui.Button(u8"Удалить существующую радиостанцию")
    imgui.End()
end
1586803404927.png
 

Quasper

Известный
835
354
Как сделать так, чтобы при нажатии кнопки "Создать новую радиостанцию", я попадал в меню с кнопками "Ссылка на видеоролик, либо прямую трансляцию" и "Удалить существующую радиостанцию"? День мучаюсь, не могу найти. Подкину репы
Lua:
function imgui.OnDrawFrame()
    imgui.Begin(u8"[Онлайн радио v0.9]", main_window_state)
    if imgui.Button(u8"Создать новую радиостанцию") then
        imgui.Button(u8"Ссылка на видеоролик, либо прямую трансляцию")
        imgui.Button(u8"Название радиостанции, отображаемое в игре")
    end
    imgui.Button(u8"Настройки существующих радиостанций")
    imgui.Button(u8"Удалить существующую радиостанцию")
    imgui.End()
end
Посмотреть вложение 53426

Lua:
--где то в начале
local newStation = false

--B Begin'e
    if imgui.Button(u8"Создать новую радиостанцию") then
        newStation = not newStation
    end
    if newStation then
        imgui.Button(u8"Ссылка на видеоролик, либо прямую трансляцию")
        imgui.Button(u8"Название радиостанции, отображаемое в игре")
    end
Нажмешь на "Создать новую станцию" появятся 2 новые кнопочки, нажмешь ещё раз - пропадут. Думаю принцип понятен :)
 
  • Нравится
Реакции: vodya

langerdovers

Участник
96
22
Из-за чего не открывается Popup?

Lua:
if imgui.BeginPopup("confirm_dialog") then
    imgui.Text(u8"Подтвердите действие")
    if imgui.Button(u8"Удалить") then
        sampAddChatMessage('Удалено!',-1)
        imgui.CloseCurrentPopup()
    end
    imgui.SameLine()
    if imgui.Button(u8"Отмена") then
        sampAddChatMessage('Отмена', -1)
        imgui.CloseCurrentPopup()
    end
    imgui.EndPopup()
end
if imgui.CollapsingHeader(u8'Дружественные скины') then
    imgui.InputText(u8"Введите ID скина",skin_id_buffer,imgui.InputTextFlags.CharsDecimal)
    if imgui.Button(u8'Добавить##20') then
        sampAddChatMessage('add',-1)
     end
    imgui.BeginChild(u8"Список", imgui.ImVec2((imgui.GetWindowWidth() - 28),150 ), true)
        imgui.Columns(2, "skin_coloumn")
        for i=1, #data['friend_skin_list'] do
            imgui.Separator()
            imgui.Text(u8'ID скина:' .. data['friend_skin_list'][i])
            imgui.NextColumn()
            if imgui.Button(u8'Удалить##20'..i) then
                to_del_skin = i
                imgui.OpenPopup('confirm_dialog')
            end
            imgui.NextColumn()
        end
    imgui.EndChild()
end
 
Последнее редактирование:

lemonager

Известный
Всефорумный модератор
809
1,720
Подскажите пожалуйста как загрузить картинку в имгуи?
Вот такой код почему-то не работает. Картинка просто не появляется.
(не знаю какие аргументы что значат, но строчку я взял из Imgui Scoreboard с функцией добавить картинку на задний фон)
Lua:
------------------------------------------------------
local background = nil
---------------------------------------------------------
if doesFileExist("C:\\Games\\GTA San Andreas(osn)\\moonloader\\resource\\wind.png") then
    background = imgui.CreateTextureFromFile("C:\\Games\\GTA San Andreas(osn)\\moonloader\\resource\\wind.png")
else
    background = nil
end
---------------------------------------------
if imgui.Button(u8'123', imgui.ImVec2(70, 0)) then
    ima.v = not ima.v
end
if ima.v and background then
    imgui.Separator()
    imgui.Image(background, imgui.ImVec2(0 , 200), imgui.ImVec2(0, 0), imgui.ImVec2(1, 1), imgui.ImColor(155, 155, 155, 155):GetVec4())
end
----------------------------------------------

В целом код рабочий, даже нет никаких ошибок и в логе ничего нет.
Тут должна быть картинка, но появляется пустое поле с указанным размером
Посмотреть вложение 53256
Делать такой путь до изображения не вариант, сейчас покажу полностью рабочий код. Давай разберем строку ниже: скрипт получит изображение из папки с твоей гта по пути moonloader/res/image.png
getGameDirectory()Директория до твоей папки с гта ( не зависит от диска )
moonloaderпапка с скриптом \ скриптами
res папка для удобного хранения картинки ( можно убрать)
image.png твоя картинка
Lua:
img = imgui.CreateTextureFromFile(getGameDirectory() .. '\\moonloader\\res\\image.png')
img - это твоя переменная, которую ты будешь использовать в onDrawFrame
это должно находиться в main, после проверки на загрузку сампа
Lua:
 while not isSampAvailable() do wait(100) end
После того как ты выполнил все выше написанное можно перейти в onDrawFrame
Lua:
imgui.Image(img, imgui.ImVec2(150, 150))
это вставляем в любое желаемое место onDrawFrame, 150 и 150 это размеры картинки по X и Y ( меняешь на свои любые ). Если ты захочешь передвинуть картинку куда либо, то используй перед imgui.image:
Lua:
imgui.SetCursorPos(imgui.ImVec2(250, 100))
250(X) и 100(Y) это координаты нашей картинки в имгуи окошке, выглядеть это должно вот так:
1587204817028.png

После правильно выполненных действий мы увидим заветную картинку:
1587204986327.png
 
  • Нравится
Реакции: deadfamq

LAZLEE

Известный
216
23
КАК АКТИВИРОВАТЬ?
Я В ЧАТ ЧТО ТО ПИСАЛ И СЛУЧАЙНО ОКОШКО ЭТОГО ВЫЛЕЗЛО И Я НАЖАЛ НА ЧТО ТО ТЕПЕРЬ ТОЛЬКО МЫШКА ОДНА И КАМЕРОЙ ШЕВЕЛИТЬ НЕ МОГУ
 

AnWu

Известный
Всефорумный модератор
4,777
5,402
КАК АКТИВИРОВАТЬ?
Я В ЧАТ ЧТО ТО ПИСАЛ И СЛУЧАЙНО ОКОШКО ЭТОГО ВЫЛЕЗЛО И Я НАЖАЛ НА ЧТО ТО ТЕПЕРЬ ТОЛЬКО МЫШКА ОДНА И КАМЕРОЙ ШЕВЕЛИТЬ НЕ МОГУ
удали демо скрипт и не пиши капсом
 

paulohardy

вы еще постите говно? тогда я иду к вам
Всефорумный модератор
1,920
1,292
ок, а этот же демо требуют многие скрипты, они разве будут работать без него?
демо - версия скрипта показывающая возможности imgui, она не нужна для других скриптов
 

Royan_Millans

Известный
145
183
Lua:
imgui.Image(imgui_images.banner, imgui.ImVec2(520, 100))

            imgui.SetCursorPosY(84)
            imgui.SetCursorPosX(480)
            imgui.TextColoredRGB(u8"{FFFFFF}Версия скрипта: "..thisScript().version)

            imgui.SetCursorPosY(80)
            imgui.SetCursorPosX(610)
            if imgui.Button(u8"Что нового?") then
                selected = 101

                if update_information == nil then
                    lua_thread.create(function ()
                        wait(0)
                        asyncHttpRequest("GET", "TUT URL", nil,
                        function(response)
                            if response.text:find("version") then
                                update_information = decodeJson(response.text)
                            else
                                update_information = "error"
                            end

                        end,
                        function(err)
                            update_information = "error"
                        end)
                    end)

                end

            end

            imgui.Spacing()


            imgui.SetCursorPosY(150)
            imgui.Text(u8"Информация о Вас:")

            imgui.BeginChild("about_me", imgui.ImVec2(200, 65), true)

                if secure_info.hospital == 1 then
                    imgui.TextColoredRGB(u8"Мед. Центр: {c24f00}Floris")
                elseif secure_info.hospital == 2 then
                    imgui.TextColoredRGB(u8"Мед. Центр: {c24f00}St. Francis")
                elseif secure_info.hospital == 3 then
                    imgui.TextColoredRGB(u8"Мед. Центр: {c24f00}Kindred")
                elseif secure_info.hospital == 4 then
                    imgui.TextColoredRGB(u8"Место работы: {c24f00}АП")
                else
                    imgui.TextColoredRGB(u8"Мед. Центр: {595959}Проверка")
                end

            if secure_info.rang ~= nil then
                imgui.TextColoredRGB(u8"Ранг: {c24f00}"..secure_info.rang)
            else
                imgui.TextColoredRGB(u8"Ранг: {595959}Проверка")
            end

            imgui.EndChild()

            imgui.Spacing()

            imgui.Text(u8"Техническая информация:")

            imgui.BeginChild("status_script", imgui.ImVec2(200, 109), true, imgui.WindowFlags.NoScrollWithMouse + imgui.WindowFlags.NoScrollbar)

                if script_status == "active" then

                    imgui.TextColoredRGB(u8"Проверка обновлений: \n{15ff00}Последняя версия")
                    imgui.SetCursorPos(imgui.ImVec2(130, 34))
                    if imgui.Button(fa.ICON_FA_REDO) then
                        message("Проверка обновлений..")
                        lua_thread.create(function ()
                            wait(0)
                            asyncHttpRequest("GET", "TUT_URL", nil,
                            function(response)
                                if response.text:find("version_number") then
                                    local update_info = decodeJson(response.text)

                                    if tonumber(update_info['version_number']) ~= thisScript().version_num then
                                        message("Происходит обновление до версии "..update_info['version']..'..')

                                        downloadUrlToFile(update_info['url'], thisScript().path, function (id, status, p1, p2)
                                            if status == dlstatus.STATUS_ENDDOWNLOADDATA then

                                                message("Обновление успешно завершено!")

                                                if not doesFileExist(getWorkingDirectory() .. "\\AutoReboot.lua") then
                                                    script_reload()
                                                else
                                                    script_reload_status = true
                                                end

                                            end  
                                        end)
                                    else
                                        message("Обновлений не найдено.")
                                    end
                                else
                                    message("Скрипту не удалось проверить обновления.")
                                end

                            end,
                            function(err)
                                message("Скрипту не удалось проверить обновления.")
                            end)
                        end)

                    end

                elseif script_status == "offline_active" then

                    imgui.TextColoredRGB(u8"Проверка обновлений: \n{cc0030}Оффлайн режим")

                end

                imgui.SetCursorPosY(65)

                if secure_info.status == "wait_stats" then

                    imgui.TextColoredRGB(u8"Соеденение с сервером MZS: \n{15ff00}Установлено")

                elseif secure_info.status == "wait" then

                    imgui.TextColoredRGB(u8"Соеденение с сервером MZS: \n{e65800}Авторизация..")

                elseif secure_info.status == "error" then

                    imgui.TextColoredRGB(u8"Соеденение с сервером MZS: \n{cc0030}Ошибка авторизации")

                elseif secure_info.status == "active" then

                    imgui.TextColoredRGB(u8"Соеденение с сервером MZS: \n{e65800}Ожидание..")

                end

            imgui.EndChild()

            imgui.SetCursorPosX(390)
            imgui.SetCursorPosY(150)
            imgui.Text(u8"Новости от министра:")


            imgui.SetCursorPosX(390)
            imgui.SetCursorPosY(172)
            imgui.BeginChild("news", imgui.ImVec2(0, 0), true)

                if (secure_info.rang == 11 or GetNickName() == "Royan_Millans") and secure_info.token ~= nil then
                    if imgui.RedButton(fa.ICON_FA_TABLET_ALT..u8" Панель Министра [СЕКРЕТНО]", imgui.ImVec2(-0.1, 50)) then

                        selected = 102

                    end

                elseif (secure_info.rang == 11 or GetNickName() == "Royan_Millans") and secure_info.token == nil then

                    imgui.DisableButton(u8"Происходит авторизация..", imgui.ImVec2(-0.1, 50))

                end

                if news_list == nil then

                    imgui.Text(imgui.Text(fa.ICON_FA_SPINNER..u8(" Получение данных с сервера..")))

                elseif news_list == "error" then

                    imgui.Text(fa.ICON_FA_EXCLAMATION..u8(" Произошла ошибка во время получения данных с сервера, попробуйте позже."))

                elseif news_list == "nope" then


                    imgui.SetCursorPosX(70)
                    imgui.Text(fa.ICON_FA_SEARCH..u8(" Новостей не найдено"))

                else

                    for k, v in pairs(news_list) do

                        local status = true
   
                        for k2, v2 in pairs(check_news) do
                            if v2 == v.id then
                               status = false
                            end
                        end
                       
                        if status then
                               if imgui.NotificationButton(fa.ICON_FA_BELL.." #"..v.id.." "..v.caption, imgui.ImVec2(-0.1, 30)) then


                                   table.insert(check_news, v.id)
                                   lua_thread.create(function ()
                                    wait(0)
                                       local json = encodeJson(check_news)
                                    local handle = io.open(getWorkingDirectory() .. "\\MZ Senior\\check_news.json", "w")
                                    handle:write(json)
                                    handle:close()
                                end)

                                news_info.key = k

                                selected = 110


                               end
                        else
                            if imgui.Button("#"..v.id.." "..v.caption, imgui.ImVec2(-0.1, 30)) then

                                news_info.key = k
                                news_info.selected = selected

                                selected = 110
                            end
                        end

                    end

                end

            imgui.EndChild()

Открывается, все вроде бы работает, но через пару секунд крашит игру, в чем проблема?
 
Последнее редактирование:

tashernonyb

Новичок
10
0
Я добавил само меню которое приведено в 1 странице, и добавил текст. При нажатии на текст выскакивает внизу обычных текст и он сразу пропадает. Как сделать так чтобы при нажатии на текст к примеру "информация" выскакивала ещё одно окно с информацией, и оно так-же могло закрываться.
Вот код сам

if imgui.Button('Press me') then -- а вот и кнопка с действием
-- условие будет выполнено при нажатии на неё
printStringNow('Button pressed!', 1000)
 

Royan_Millans

Известный
145
183
Я добавил само меню которое приведено в 1 странице, и добавил текст. При нажатии на текст выскакивает внизу обычных текст и он сразу пропадает. Как сделать так чтобы при нажатии на текст к примеру "информация" выскакивала ещё одно окно с информацией, и оно так-же могло закрываться.
Вот код сам

Lua:
-- В начало скрипта
status_show_text = false


function imgui.OnDrawFrame()

    if imgui.Button('Press me') then -- а вот и кнопка с действием
        status_show_text = not status_show_text -- Меняем значение status_show_text на противоположное, то есть было false, стало true (и наоборот)
    end
    
    if status_show_text then -- если у нас status_show_text, то выполняются все действия внутри
        printStringNow('Button pressed!', 1000) -- выводим текст (задержку wait если что в imgui юзать запрещено)
    end

end