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

Grid widget #428

Closed
ghost opened this issue Dec 8, 2015 · 2 comments
Closed

Grid widget #428

ghost opened this issue Dec 8, 2015 · 2 comments

Comments

@ghost
Copy link

ghost commented Dec 8, 2015

Hi,

I try to create a "grid" widget that will contains a set of selectable item.

Each item is composed of a text and an image.

So, I'm not sure it is the best way to start, but I'm trying to use the ImageButton... the problem is that:

  • I cannot display a text behind, the selection is only over the button
  • There is no "selection", just able to press the button. Does "Selectable" can work with Images ?
@ghost
Copy link
Author

ghost commented Dec 8, 2015

Here is my code, it is far to be perfect, so any suggestion is welcomed:

I still see some important improvements to do :

  • create a widget for a more general usage (without std::string usage)
  • allow to zoom/unzoom to have bigger/smaller items
  • more style options
  • add tooltips

void Browser::DrawTemplates(TemplateCategory* category)
{
ImVec2 os = ImGui::GetCursorScreenPos();
ImVec2 origin = ImGui::GetCursorPos();

float x = 0.f;
float y = 0.f;

for (unsigned int i = 0; i < category->Templates.size(); i++)
{
    ImGui::PushID(i);

    //----
    ImGuiWindow* window = GetCurrentWindow();
    const ImGuiID id = window->GetID(category);

    bool out_hovered;
    bool out_held;
    // bool pressed = ImGui::ButtonBehavior(ImRect(x, y, x + 120, y + 120), id, &out_hovered, &out_held, true, ImGuiButtonFlags_PressedOnClick);
    // bool          IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs = false);

    ImVec2 mousePos = ImGui::GetMousePos();
    mousePos.x -= os.x;
    mousePos.y -= os.y;
    out_hovered = (mousePos.x > x && mousePos.x < x + 120 && mousePos.y > y && mousePos.y < y + 120);

    //---- Selection
    if (out_hovered)
    {
        ImU32 col = ImColor(ImGui::GetStyle().Colors[ImGuiCol_HeaderHovered]);
        x += os.x;
        y += os.y;
        ImGui::RenderFrame(ImVec2(x, y), ImVec2(x + 120, y + 120), col, true, 3.f);
        x -= os.x;
        y -= os.y;
    }

    //---- Image
    ImGui::SetCursorPosX(x + origin.x + 10);
    ImGui::SetCursorPosY(y + origin.y + 10);
    CreateTexture(category->Templates[i]);
    ImGui::Image(category->Templates[i]->TextureId, ImVec2(100, 100));

    //---- Text
    ImGui::SetCursorPosX(x + origin.x + 10);
    ImGui::SetCursorPosY(y + origin.y + 120);
    ImGui::PushFont(UIStyle::GetTextFont());

    string name = category->Templates[i]->Name;
    if (name.length() > 8)
        name = name.substr(0, 8) + "...";
    ImGui::Text(name.c_str());

    ImGui::PopFont();

    //---- Next position
    x += 120;
    if (x+120 > ImGui::GetWindowWidth())
    {
        x = 0;
        y += 140;
    }

    ImGui::PopID();
}

}

@ocornut
Copy link
Owner

ocornut commented Dec 24, 2015

I'm closing this as there isn't really a single answer forward. The code above may be good as a suggestion to new ImGui users and perhaps we can provide more examples in the demo. but otherwise there's nothing really special or reusable about that code.

It's however a really good example case. Right now using BeginChild() may make it easier and more natural to create independent boxes with their own clipping, but children windows have a bit of an overhead that could be reduced. BeginGroup+PushClipRect may also provide similar result with less overhead.

Ideally we'd want to go toward lowering the overhead of BeginChild or clarifying exactly what it means, or providing lower-level primitives that say, combine column locking (like BeginGroup) + clipping rectangle (like PushClipRect), with an additional way to either merge draw calls when output hasn't extended past its clipping bounds (need to maintain bounding box of output), or add CPU-side clipping to all non-text primitives. Those features will be essential to add more natural layout features with generalised clipping without overhead.

Sorry I am just thinking aloud there! (for my own reference)

Loosely relate to #404.

@ocornut ocornut closed this as completed Dec 24, 2015
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