Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TimeLine tracker. How reduce his code for ImGui #1014

Open
colesnicov opened this issue Feb 10, 2017 · 0 comments
Open

TimeLine tracker. How reduce his code for ImGui #1014

colesnicov opened this issue Feb 10, 2017 · 0 comments

Comments

@colesnicov
Copy link

colesnicov commented Feb 10, 2017

(excuse me for my bad english)
Hi guys. I've try to create small MP3 Player and i created timetracker/slider with back propagation and callbacks for formating values for overlays. I grabbed the code from ImGui::ProgresBar(...) and modify is. But i see what its a lot of code. If you see best way to reduce the code or any other hints to modify for better result?

timeslider/tracker

And I don't know why, but the formatting function produce the shits... As You can see on screen the text PA on overlay of tracker did have be float values formatted as f.ff/f.ff :-/

:)

code:

void Tracker(float current, float duration, float* tracked = NULL, const ImVec2& size_arg = ImVec2(-1, 0),
             const char* (*overlay_cb)(float progress, float duration) = nullptr,
             const char* (*tooltip_cb)(float progress, float duration) = nullptr)
{
    // Check for bad values and write is to sto
    const char* error = "";
    if((current > 0.0f && duration == 0.0f) || current > duration) // has error
    {
        std::cerr << "current progress '" << current << "' is too big as total duration '" << duration << "'" << std::endl;
        current = 0.0f;
        error = "error";
    }

    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (window->SkipItems)
    {
        return;
    }

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;
    // Calculate BBOX
    ImVec2 pos = window->DC.CursorPos;
    ImRect bb(pos, pos + ImGui::CalcItemSize(size_arg, ImGui::CalcItemWidth(), g.FontSize + style.FramePadding.y*2.0f));
    ImGui::ItemSize(bb, style.FramePadding.y);
    if (!ImGui::ItemAdd(bb, NULL))
    {
        return;
    }

    // Render tracker
    current = 1.0f / (duration / current);
    ImGui::RenderFrame(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
    bb.Reduce(ImVec2(window->BorderSize, window->BorderSize));
    const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, current), bb.Max.y);
    ImGui::RenderFrame(bb.Min, fill_br, ImGui::GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding);

    // Stop render if has error
    if(strlen(error)>0)
    {
        ImGui::RenderText(ImVec2(bb.Min + (bb.GetSize() - ImGui::CalcTextSize(error)) / 2), error);
        return;
    }
    // Calculate overlap
    ImVec2 bb_closets = bb.GetClosestPoint(ImGui::GetIO().MousePos, true);
    float mousePosition = bb_closets.x - pos.x;
    float percent =1.0f / (bb.GetSize().x / mousePosition);

    if(duration > 0.0f)
    {
        // Check if hovered and clicked
        //ImGuiButtonFlags button_flags = ImGuiButtonFlags_PressedOnClick|ImGuiButtonFlags_PressedOnClickRelease|ImGuiButtonFlags_PressedOnRelease
        bool hovered;
        bool pressed = ImGui::ButtonBehavior(bb, NULL, &hovered, NULL, ImGuiButtonFlags_PressedOnClick);

        if(pressed && tracked) // Has click event
        {
            *tracked = percent * 100;
        }

        if(hovered) // Has hover event
        {
            // Render overlap
            ImGui::RenderFrame(bb.Min, ImVec2(ImLerp(bb.Min.x, bb.Max.x, percent), bb.Max.y), ImColor(180, 180, 255, 150), false, style.FrameRounding);
            if(tooltip_cb != nullptr) // Has on mouse hover callback for tooltip format
            {
                const char* tooltip = tooltip_cb(percent, duration);
                ImGui::SetTooltip("%s", tooltip);
            }
        }
    }

    if (overlay_cb != nullptr) // Has overlay format callback
    {
        // Calculate BBOX and render overlay text
        const char* overlay = overlay_cb(percent, duration);
        ImVec2 overlay_size = ImGui::CalcTextSize(overlay);
        ImGui::RenderText(ImVec2(bb.Min + (bb.GetSize() - overlay_size) / 2), overlay);
    }
}

usage:

ImGui::Begin("Time tracker", NULL, ImGuiWindowFlags_ShowBorders);
{
  static float current = 0.0f;
  float duration = 10.0f;
  float tracked = 0.0f;
  siz(300, 50);
  Tracker(current, duration, &tracked, siz, [](float progress, float duration) -> const char*
  {
    char buf[50];
    ImFormatString(buf, IM_ARRAYSIZE(buf), "%.2f/%.2f", progress, duration);
    const char* str(buf);
    return str;
    });
  ImGui::SliderFloat("Current", &current, .0f, 100.f);
  ImGui::SliderFloat("Duration", &duration, .0f, 100.f);
  ImGui::Text("Tracked: %f", tracked);
}
ImGui::End();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant