получить поведение кнопки (hovered/active) mimgui.

whyhardlyz

Известный
Автор темы
120
90
Версия MoonLoader
.026-beta
Возник вопрос, как получить поведение кнопки в mimgui, то есть, наведен ли курсор на кнопку? или же на кнопку нажали? Если в плюсах это намного проще, то как в mimgui?


C++:
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
 

SomaGnoma

Известный
429
148
Возник вопрос, как получить поведение кнопки в mimgui, то есть, наведен ли курсор на кнопку? или же на кнопку нажали? Если в плюсах это намного проще, то как в mimgui?


C++:
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
Код:
_Bool                igIsItemHovered(ImGuiHoveredFlags flags);
_Bool                igIsItemActive(void);
_Bool                igIsItemFocused(void);
_Bool                igIsItemClicked(int mouse_button);
_Bool                igIsItemVisible(void);
_Bool                igIsItemEdited(void);
_Bool                igIsItemActivated(void);
_Bool                igIsItemDeactivated(void);
_Bool                igIsItemDeactivatedAfterEdit(void);
_Bool                igIsAnyItemHovered(void);
_Bool                igIsAnyItemActive(void);
_Bool                igIsAnyItemFocused(void);
Значит шобы отследить наведение или клик то
Lua:
imgui.Button("Nigaa")
if imgui.IsItemHovered() then
    print("Ты навел курсор на кнопку")
end
 

whyhardlyz

Известный
Автор темы
120
90
здесь такой функции нет, но можно вручную смастерить через IsItemHovered, IsItemActive
Как тут?


Lua:
function imgui.AnimatedButton(label, size, speed, rounded)
    local size = size or imgui.ImVec2(0, 0)
    local bool = false
    local text = label:gsub('##.+$', '')
    local ts = imgui.CalcTextSize(text)
    speed = speed and speed or 0.4
    if not AnimatedButtons then AnimatedButtons = {} end
    if not AnimatedButtons[label] then
        local color = imgui.GetStyle().Colors[imgui.Col.ButtonHovered]
        AnimatedButtons[label] = {circles = {}, hovered = false, state = false, time = os.clock(), color = imgui.ImVec4(color.x, color.y, color.z, 0.2)}
    end
    local button = AnimatedButtons[label]
    local dl = imgui.GetWindowDrawList()
    local p = imgui.GetCursorScreenPos()
    local c = imgui.GetCursorPos()
    local CalcItemSize = function(size, width, height)
        local region = imgui.GetContentRegionMax()
        if (size.x == 0) then
            size.x = width
        elseif (size.x < 0) then
            size.x = math.max(4.0, region.x - c.x + size.x);
        end
        if (size.y == 0) then
            size.y = height;
        elseif (size.y < 0) then
            size.y = math.max(4.0, region.y - c.y + size.y);
        end
        return size
    end
    size = CalcItemSize(size, ts.x+imgui.GetStyle().FramePadding.x*2, ts.y+imgui.GetStyle().FramePadding.y*2)
    local ImSaturate = function(f) return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f) end
    if #button.circles > 0 then
        local PathInvertedRect = function(a, b, col)
            local rounding = rounded and imgui.GetStyle().FrameRounding or 0
            if rounding <= 0 or not rounded then return end
            local dl = imgui.GetWindowDrawList()
            dl:PathLineTo(a)
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, a.y + rounding), rounding, -3.0, -1.5)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(b.x, a.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, a.y + rounding), rounding, -1.5, -0.205)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(b.x, b.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, b.y - rounding), rounding, 1.5, 0.205)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(a.x, b.y))
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, b.y - rounding), rounding, 3.0, 1.5)
            dl:PathFillConvex(col)
        end
        for i, circle in ipairs(button.circles) do
            local time = os.clock() - circle.time
            local t = ImSaturate(time / speed)
            local color = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
            local color = imgui.GetColorU32Vec4(imgui.ImVec4(color.x, color.y, color.z, (circle.reverse and (255-255*t) or (255*t))/255))
            local radius = math.max(size.x, size.y) * (circle.reverse and 1.5 or t)
            imgui.PushClipRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), true)
            dl:AddRectFilled(p, imgui.ImVec2(p.x+size.x, p.y+size.y), color) -- from circle to rect
            PathInvertedRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32Vec4(imgui.GetStyle().Colors[imgui.Col.WindowBg]))
            imgui.PopClipRect()
            if t == 1 then
                if not circle.reverse then
                    circle.reverse = true
                    circle.time = os.clock()
                else
                    table.remove(button.circles, i)
                end
            end
        end
    end
    local t = ImSaturate((os.clock()-button.time) / speed)
    button.color.w = button.color.w + (button.hovered and 0.8 or -0.8)*t
    button.color.w = button.color.w < 0.2 and 0.2 or (button.color.w > 1 and 1 or button.color.w)
    color = imgui.GetStyle().Colors[imgui.Col.Button]
    color = imgui.GetColorU32Vec4(imgui.ImVec4(color.x, color.y, color.z, 0.2))
    dl:AddRectFilled(p, imgui.ImVec2(p.x+size.x, p.y+size.y), color, rounded and imgui.GetStyle().FrameRounding or 0)
    dl:AddRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32Vec4(button.color), rounded and imgui.GetStyle().FrameRounding or 0)
    local align = imgui.GetStyle().ButtonTextAlign
    imgui.SetCursorPos(imgui.ImVec2(c.x+(size.x-ts.x)*align.x, c.y+(size.y-ts.y)*align.y))
    imgui.Text(text)
    imgui.SetCursorPos(c)
    if imgui.InvisibleButton(label, size) then
        bool = true
        table.insert(button.circles, {animate = true, reverse = false, time = os.clock(), clickpos = imgui.ImVec2(getCursorPos())})
    end
    button.hovered = imgui.IsItemHovered()
    if button.hovered ~= button.state then
        button.state = button.hovered
        button.time = os.clock()
    end
    return bool
end

Код:
_Bool                igIsItemHovered(ImGuiHoveredFlags flags);
_Bool                igIsItemActive(void);
_Bool                igIsItemFocused(void);
_Bool                igIsItemClicked(int mouse_button);
_Bool                igIsItemVisible(void);
_Bool                igIsItemEdited(void);
_Bool                igIsItemActivated(void);
_Bool                igIsItemDeactivated(void);
_Bool                igIsItemDeactivatedAfterEdit(void);
_Bool                igIsAnyItemHovered(void);
_Bool                igIsAnyItemActive(void);
_Bool                igIsAnyItemFocused(void);
Значит шобы отследить наведение или клик то
Lua:
imgui.Button("Nigaa")
if imgui.IsItemHovered() then
    print("Ты навел курсор на кнопку")
end
C++:
const ImRect bb(pos, ImVec2(pos.x + size.x, pos.y + size.y));
ImGui::ItemSize(size, style.FramePadding.y);
if (!ImGui::ItemAdd(bb, id))
    return false;

bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);

а если надо чтобы засчитывало клик по области "bb"?
 
Последнее редактирование:
  • Нравится
Реакции: SomaGnoma

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,651
2,550
а если надо чтобы засчитывало клик по области "bb"?
C++:
IMGUI_API bool          IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
IMGUI_API bool          IsMouseClicked(ImGuiMouseButton button, bool repeat = false);       // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1.
 

whyhardlyz

Известный
Автор темы
120
90
C++:
IMGUI_API bool          IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
IMGUI_API bool          IsMouseClicked(ImGuiMouseButton button, bool repeat = false);       // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1.
ндааа, я даже не знаю как задать "bb" значение Min, и Max, да и думаю что плюсовых возможностей имгуи нету в мимгуи, приходится делать еще кучу лишних пальцедвижений для того чтобы сделать просто свой элемент гуи
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,651
2,550
ндааа, я даже не знаю как задать "bb" значение
эти методы следует использовать, как правило, при ручном рендере через примитивы, а в твоём случае, если хочешь сделать проверку на нажатие по тексту (это же по тексту?) достаточно использовать обычные функции:
C++:
// Item/Widgets Utilities and Query Functions // - Most of the functions are referring to the previous Item that has been submitted. // - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions.
IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options.
IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited. This will continuously return true while holding mouse button on an item. Items that don't interact will always return false)
IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation?
IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item hovered and mouse clicked on? (**) == IsMouseClicked(mouse_button) && IsItemHovered()Important. (**) this it NOT equivalent to the behavior of e.g. Button(). Read comments in function definition.
IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling)
IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets.
IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive).
IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing.
IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item).
IMGUI_API bool IsItemToggledOpen(); // was the last item open state toggled? set by TreeNode().
 

whyhardlyz

Известный
Автор темы
120
90
эти методы следует использовать, как правило, при ручном рендере через примитивы, а в твоём случае, если хочешь сделать проверку на нажатие по тексту (это же по тексту?) достаточно использовать обычные функции:
C++:
// Item/Widgets Utilities and Query Functions // - Most of the functions are referring to the previous Item that has been submitted. // - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions.
IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options.
IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited. This will continuously return true while holding mouse button on an item. Items that don't interact will always return false)
IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation?
IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item hovered and mouse clicked on? (**) == IsMouseClicked(mouse_button) && IsItemHovered()Important. (**) this it NOT equivalent to the behavior of e.g. Button(). Read comments in function definition.
IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling)
IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets.
IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive).
IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing.
IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item).
IMGUI_API bool IsItemToggledOpen(); // was the last item open state toggled? set by TreeNode().
C++:
    bool Tab(const char* icon, const char* label, const char* desc, const ImVec2& size_arg, const bool selected)
    {
        ImGuiWindow* window = ImGui::GetCurrentWindow();
        if (window->SkipItems)
            return false;

        static float sizeplus = 0.f;

        ImGuiContext& g = *GImGui;
        const ImGuiStyle& style = g.Style;
        const ImGuiID id = window->GetID(label);
        const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);

        ImVec2 pos = window->DC.CursorPos;

        ImVec2 size = ImGui::CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f);

        const ImRect bb(pos, ImVec2(pos.x + size.x, pos.y + size.y)); // вроде как что-то типо квадрата
        ImGui::ItemSize(size, style.FramePadding.y); // ??????????????????
        if (!ImGui::ItemAdd(bb, id)) // ?
            return false;

        bool hovered, held;
        bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0); // ?

        if (selected)
            window->DrawList->AddRectFilled(bb.Min, bb.Max, ImColor(25, 30, 35));

        window->DrawList->AddText(ImVec2(bb.Min.x + 35, bb.Min.y + 13), ImColor(255 / 255.f, 255 / 255.f, 255 / 255.f, 255.f / 255.f), label);
        window->DrawList->AddText(ImVec2(bb.Min.x + 35, bb.Min.y + 26), ImColor(100 / 255.f, 100 / 255.f, 100 / 255.f, 255.f / 255.f), desc);

        return pressed;
    }

не понятные вещи мне я подсветил, bb - это скорее рект по которому надо зафиксировать нажатие функциями ранее тобою написанных (IsMouseHoveringRect и IsMouseClicked) но тут лично мне не понятно как этот рект создать собственно