-- юзать можно так:
function Header:new(name, actived, action)
local public = {}
public.name = u8(name)
public.actived = new.bool(actived)
public.render = action
setmetatable(public, self)
self.__index = self; return public
end
local header = {
Header:new("Первая", true, function() -- в этой функции мы указываем то, что будет отображаться при нажатие на вкладку
imgui.Text("1")
end),
Header:new("Вторая", false, function()
imgui.Text("2")
end),
Header:new("Третья", false, function()
imgui.Text("3")
end),
Header:new("Четвертая", false, function()
imgui.Text("4")
end)
}
-- в imgui
imgui.BeginGroup()
for i, class in ipairs(header) do
if imgui.HeaderButton(class.actived[0], class.name) then
for j, class in ipairs(header) do
class.actived[0] = (i == j)
end
end
if (i ~= #header) then
imgui.SameLine()
end
end
imgui.EndGroup()
imgui.BeginGroup()
for _, class in ipairs(header) do
if class.actived[0] then
class:render()
end
end
imgui.EndGroup()
--------
function imgui.HeaderButton(bool, str_id)
local ToU32 = imgui.ColorConvertFloat4ToU32
local AI_HEADERBUT = {}
local DL = imgui.GetWindowDrawList()
local result = false
local label = string.gsub(str_id, "##.*$", "")
local duration = { 0.5, 0.3 }
local cols = {
idle = imgui.GetStyle().Colors[imgui.Col.TextDisabled],
hovr = imgui.GetStyle().Colors[imgui.Col.Text],
slct = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
}
if not AI_HEADERBUT[str_id] then
AI_HEADERBUT[str_id] = {
color = bool and cols.slct or cols.idle,
clock = os.clock() + duration[1],
h = {
state = bool,
alpha = bool and 1.00 or 0.00,
clock = os.clock() + duration[2],
}
}
end
local pool = AI_HEADERBUT[str_id]
imgui.BeginGroup()
local pos = imgui.GetCursorPos()
local p = imgui.GetCursorScreenPos()
imgui.TextColored(pool.color, label)
local s = imgui.GetItemRectSize()
local hovered = isPlaceHovered(p, imgui.ImVec2(p.x + s.x, p.y + s.y))
local clicked = imgui.IsItemClicked()
if pool.h.state ~= hovered and not bool then
pool.h.state = hovered
pool.h.clock = os.clock()
end
if clicked then
pool.clock = os.clock()
result = true
end
if os.clock() - pool.clock <= duration[1] then
pool.color = bringVec4To(
imgui.ImVec4(pool.color),
bool and cols.slct or (hovered and cols.hovr or cols.idle),
pool.clock,
duration[1]
)
else
pool.color = bool and cols.slct or (hovered and cols.hovr or cols.idle)
end
if pool.h.clock then
if os.clock() - pool.h.clock <= duration[2] then
pool.h.alpha = bringFloatTo(
pool.h.alpha,
pool.h.state and 1.00 or 0.00,
pool.h.clock,
duration[2]
)
else
pool.h.alpha = pool.h.state and 1.00 or 0.00
if not pool.h.state then
pool.h.clock = nil
end
end
local max = s.x / 2
local Y = p.y + s.y + 3
local mid = p.x + max
DL:AddLine(imgui.ImVec2(mid, Y), imgui.ImVec2(mid + (max * pool.h.alpha), Y), ToU32(set_alpha(pool.color, pool.h.alpha)), 3)
DL:AddLine(imgui.ImVec2(mid, Y), imgui.ImVec2(mid - (max * pool.h.alpha), Y), ToU32(set_alpha(pool.color, pool.h.alpha)), 3)
end
imgui.EndGroup()
return result
end
function set_alpha(color, alpha)
alpha = alpha and limit(alpha, 0.0, 1.0) or 1.0
return imgui.ImVec4(color.x, color.y, color.z, alpha)
end
function isPlaceHovered(a, b)
local m = imgui.GetMousePos()
if m.x >= a.x and m.y >= a.y then
if m.x <= b.x and m.y <= b.y then
return true
end
end
return false
end
function bringVec4To(from, to, start_time, duration)
local timer = os.clock() - start_time
if timer >= 0.00 and timer <= duration then
local count = timer / (duration / 100)
return imgui.ImVec4(
from.x + (count * (to.x - from.x) / 100),
from.y + (count * (to.y - from.y) / 100),
from.z + (count * (to.z - from.z) / 100),
from.w + (count * (to.w - from.w) / 100)
), true
end
return (timer > duration) and to or from, false
end
function limit(v, min, max)
min = min or 0.0
max = max or 1.0
return v < min and min or (v > max and max or v)
end