Исходник [ImGui] Pie

trefa

Известный
Всефорумный модератор
2,097
1,230
Да мне всего-то нужно, чтобы твой код работал, но этого не происходит

Lua:
local imgui = require("imgui")
local pie_mode = imgui.ImBool(true) -- режим PieMenu
local pie_keyid = 1 -- 0 ЛКМ, 1 ПКМ, 2 СКМ
local pie_elements =
{
  {name = 'Сказать привет', action = function() sampSendChat('Привет.') end, next = nil},
  {name = 'Сказать пока', action = function() sampSendChat('Пока.') end, next = nil},
  {name = 'Сказать что-то', action = function() end, next = {
    {name = 'Сказать как дела', action = function() sampSendChat('Как дела.') end, next = nil},
    {name = 'Сказать ку-ку', action = function() sampSendChat('Ку-ку.') end, next = nil},
    {name = 'Сказать дароу', action = function() sampSendChat('Дароу.') end, next = nil}
  }}
}
if pie_mode.v then
    if imgui.IsMouseClicked(pie_keyid) then imgui.OpenPopup('PieMenu') end
    if pie.BeginPiePopup('PieMenu', pie_keyid) then
      for k, v in ipairs(pie_elements) do
        if v.next == nil then if pie.PieMenuItem(u8(v.name)) then v.action() end
        elseif type(v.next) == 'table' then drawPieSub(v) end
      end
      pie.EndPiePopup()
    end
end
imgui.ShowCursor = (pie_mode.v and imgui.IsMouseDown(pie_keyid))
function drawPieSub(v)
  if pie.BeginPieMenu(u8(v.name)) then
    for i, l in ipairs(v.next) do
      if l.next == nil then
        if pie.PieMenuItem(u8(l.name)) then l.action() end
      elseif type(l.next) == 'table' then
        drawPieSub(l)
      end
    end
    pie.EndPieMenu()
  end
end

16. attempt to index global 'pie' (a nil value)
"юзает модуль pie, не подключив его" :facepalm2:
 

Frixen

Известный
131
8
Как сделать чтобы Pie всегда открывалось по центру экрана, а не привязана к последним координатам курсора?
 

Belo4ka_belka

Известный
191
7
Привет. Решил склепать что-нибудь с помощью данной либы, но столкнулся с проблемой, что нужно вручную прописывать названия для элементов, а также функции, да и создавать саб-меню в некоторых моментах было просто не удобно. Было принято решение создать массив, который работал бы примерно также, как в реализации FYP'овских диалогов - на самом деле очень интересный механизм. В конечном итоге всё было написано и имело работоспособный вид. Начнём.

Сначала, как и всегда, в начале кода создаём переменные:
Lua:
local pie_mode = imgui.ImBool(true) -- режим PieMenu
local pie_keyid = 2 -- 0 ЛКМ, 1 ПКМ, 2 СКМ
local pie_elements =
{
  {name = 'Сказать привет', action = function() sampSendChat('Привет.') end, next = nil},
  {name = 'Сказать пока', action = function() sampSendChat('Пока.') end, next = nil},
  {name = 'Сказать что-то', action = function() end, next = {
    {name = 'Сказать как дела', action = function() sampSendChat('Как дела.') end, next = nil},
    {name = 'Сказать ку-ку', action = function() sampSendChat('Ку-ку.') end, next = nil},
    {name = 'Сказать дароу', action = function() sampSendChat('Дароу.') end, next = nil}
  }}
}
Как мы видим, у нас есть три переменные. Переменная pie_mode отвечает за активность нашего меню. Если ровнять эту переменную к false, то меню просто напросто не будет появляться. Потом идёт pie_keyid, которая равна два. Эта переменная задаёт кнопку мыши, по которой будет открываться меню. После идёт массив pie_elements, который содержит все настройки элементов меню. Всё просто: name - название текущего элемента, action - функция текущего элемента, next - следующие элементы, если речь идёт о саб-меню. Кстати, если next содержит в себе таблицу, то action не выполняется, так что функцию можно оставить пустой. Теперь переходим в main и добавляем в одно из условий imgui.Process переменную pie_mode.v, чтобы ImGUI был активен - думаю, что это понятно. Переходим в imgui.onDrawFrame - тут самое интересное. Добавляем в самый конец функции это:
Lua:
if pie_mode.v then
    if imgui.IsMouseClicked(pie_keyid) then imgui.OpenPopup('PieMenu') end
    if pie.BeginPiePopup('PieMenu', pie_keyid) then
      for k, v in ipairs(pie_elements) do
        if v.next == nil then if pie.PieMenuItem(u8(v.name)) then v.action() end
        elseif type(v.next) == 'table' then drawPieSub(v) end
      end
      pie.EndPiePopup()
    end
end
Также не забудьте привести вашу мышку в состояние и указать, что активироваться нужно только, если активен pie_mode.v и зажата кнопка активации. Если у вас уже есть ShowCursor, то добавляем в конец условия.
Lua:
imgui.ShowCursor = (pie_mode.v and imgui.IsMouseDown(pie_keyid))
Осталось немного - дописать функцию построения саб-меню. Дописываем в конец скрипта:
Lua:
function drawPieSub(v)
  if pie.BeginPieMenu(u8(v.name)) then
    for i, l in ipairs(v.next) do
      if l.next == nil then
        if pie.PieMenuItem(u8(l.name)) then l.action() end
      elseif type(l.next) == 'table' then
        drawPieSub(l)
      end
    end
    pie.EndPieMenu()
  end
end
В конечном итоге получаем вот такое вот красивое меню:
Найдете говнокод - сорян. Уж сильно сгорел с некоторых моментов либы.
Массив, кстати, можно заполнять по ходу выполнения кода. Жду новые MVDHelper'ы.
Спасибо большое, отличный метод. Возможность создавать менюшки с всегда разным количеством элементов то, что я искал. Есть ещё один вопрос: возможно ли поставить клавишу активации действия не только на мышку? Сейчас скрипт выполняет действие, после того как ЛКМ будет отпущен. Возможно ли ПКМ изменить на клавишу клавиатуры? В самом ondrawframe я уже все поменял, меню отображается пока нажата клавиша Z на клавиатуре, но хотелось бы, чтобы скрит не ждал отпускания ЛКМ для совершения действия, а ждал Z.

Код:
local pie_mode = imgui.ImBool(false) -- режим PieMenu
local pie_keyid = 0 -- 0 ЛКМ, 1 ПКМ, 2 СКМ
local pie_elements =
{
  {name = 'Сказать привет', action = function() sampSendChat('Привет.') end, next = nil},
  {name = 'Сказать пока', action = function() sampSendChat('Пока.') end, next = nil},
  {name = 'Сказать что-то', action = function() end, next = {
    {name = 'Сказать как дела', action = function() sampSendChat('Как дела.') end, next = nil},
    {name = 'Сказать ку-ку', action = function() sampSendChat('Ку-ку.') end, next = nil},
    {name = 'Сказать дароу', action = function() sampSendChat('Дароу.') end, next = nil}
  }}
}

function main()
    imgui.Process = true
    while true do 
        wait(0)
        pie_mode.v = isKeyDown(key.VK_Z) and true or false
        imgui.ShowCursor = pie_mode.v
    end
end

function imgui.OnDrawFrame()
    if pie_mode.v then
        imgui.OpenPopup('PieMenu')
        if pie.BeginPiePopup('PieMenu', pie_keyid) then
          for k, v in ipairs(pie_elements) do
            if v.next == nil then if pie.PieMenuItem(u8(v.name)) then v.action() end
            elseif type(v.next) == 'table' then drawPieSub(v) end
          end
          pie.EndPiePopup()
        end
    end
end

function drawPieSub(v)
  if pie.BeginPieMenu(u8(v.name)) then
    for i, l in ipairs(v.next) do
      if l.next == nil then
        if pie.PieMenuItem(u8(l.name)) then l.action() end
      elseif type(l.next) == 'table' then
        drawPieSub(l)
      end
    end
    pie.EndPieMenu()
  end
end
 

Pakulichev

Software Developer & System Administrator
Друг
1,789
2,130
Спасибо большое, отличный метод. Возможность создавать менюшки с всегда разным количеством элементов то, что я искал. Есть ещё один вопрос: возможно ли поставить клавишу активации действия не только на мышку? Сейчас скрипт выполняет действие, после того как ЛКМ будет отпущен. Возможно ли ПКМ изменить на клавишу клавиатуры? В самом ondrawframe я уже все поменял, меню отображается пока нажата клавиша Z на клавиатуре, но хотелось бы, чтобы скрит не ждал отпускания ЛКМ для совершения действия, а ждал Z.

Код:
local pie_mode = imgui.ImBool(false) -- режим PieMenu
local pie_keyid = 0 -- 0 ЛКМ, 1 ПКМ, 2 СКМ
local pie_elements =
{
  {name = 'Сказать привет', action = function() sampSendChat('Привет.') end, next = nil},
  {name = 'Сказать пока', action = function() sampSendChat('Пока.') end, next = nil},
  {name = 'Сказать что-то', action = function() end, next = {
    {name = 'Сказать как дела', action = function() sampSendChat('Как дела.') end, next = nil},
    {name = 'Сказать ку-ку', action = function() sampSendChat('Ку-ку.') end, next = nil},
    {name = 'Сказать дароу', action = function() sampSendChat('Дароу.') end, next = nil}
  }}
}

function main()
    imgui.Process = true
    while true do
        wait(0)
        pie_mode.v = isKeyDown(key.VK_Z) and true or false
        imgui.ShowCursor = pie_mode.v
    end
end

function imgui.OnDrawFrame()
    if pie_mode.v then
        imgui.OpenPopup('PieMenu')
        if pie.BeginPiePopup('PieMenu', pie_keyid) then
          for k, v in ipairs(pie_elements) do
            if v.next == nil then if pie.PieMenuItem(u8(v.name)) then v.action() end
            elseif type(v.next) == 'table' then drawPieSub(v) end
          end
          pie.EndPiePopup()
        end
    end
end

function drawPieSub(v)
  if pie.BeginPieMenu(u8(v.name)) then
    for i, l in ipairs(v.next) do
      if l.next == nil then
        if pie.PieMenuItem(u8(l.name)) then l.action() end
      elseif type(l.next) == 'table' then
        drawPieSub(l)
      end
    end
    pie.EndPieMenu()
  end
end
Библиотека была написана под мышку. Чтобы изменить её поведение, нужно изменять саму библиотеку. Рекомендую не делать это, ибо люди любят скачивать и перекачивать оригинальный библиотеки вручную. Самый практичный способ - средняя кнопка мыши (колёсико).
 

Anton Nixon

Активный
474
48
помогите разобраться, подключил PieMenu,а оно сразу ошибки выдает
Lua:
[ML] (error) mo_helper.lua: ... Theft Auto San Andreas\moonloader\lib\imgui_piemenu.lua:5: ImGui Pie requires Moon ImGui v1.1.4 or greater
stack traceback:
    [C]: in function 'assert'
    ... Theft Auto San Andreas\moonloader\lib\imgui_piemenu.lua:5: in main chunk
    [C]: in function 'require'
 

AnWu

Guardian of Order
Всефорумный модератор
4,687
5,164
помогите разобраться, подключил PieMenu,а оно сразу ошибки выдает
Lua:
[ML] (error) mo_helper.lua: ... Theft Auto San Andreas\moonloader\lib\imgui_piemenu.lua:5: ImGui Pie requires Moon ImGui v1.1.4 or greater
stack traceback:
    [C]: in function 'assert'
    ... Theft Auto San Andreas\moonloader\lib\imgui_piemenu.lua:5: in main chunk
    [C]: in function 'require'
Нужен Moon ImGui версии 1.1.4 и младше
 

qojqva

Известный
56
2
Не работает, послушайте ребят, я умею делать биндер но почему я не могу разобраться с piemenu?

Когда у тебя просят сделать биндер
gL-S9Tf7A3E.jpg