ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.3k stars 10.11k forks source link

Highlightable/Selectable text? #950

Open degracode opened 7 years ago

degracode commented 7 years ago

I'm currently writing some logging facilities, and it'd be useful to make regular text highlightable so that the user can copy it.

So far I've been doing this using InputText/InputTextMultiLine with ImGuiInputTextFlags_ReadOnly, but it's quite awkward as you have to make a buffer, and pass it in with the length - it can't easily be used with printf formatting.

Is there already a simpler way to do this?

ocornut commented 7 years ago

There's no way currently but I agree it is desirable.

Right now a workaround is to use a context menu (right-click on the text item opening a menu that would have a "Copy" option), so you could create yourself a helper that does Text + that menu.

Linking to #949 (coincidentally filled on the same time as you): @megaton: was your intent just to copy text to clipboard and not edit it ?

hb3p8 commented 7 years ago

@ocornut Yes, that's correct :) Actually I have implemented solution with context menu a while ago, but possibility to copy only part of the text would be nice. I was extending console example a bit and felt that such a feature will look good.

nico-abram commented 5 years ago

Are there any examples of implementing the context menu with Copy?

hb3p8 commented 5 years ago

@nico-abram It is right in ImGui demo window. Look at if (ImGui::TreeNode("Context menus")) section. Just replace logic inside menu to something like this: https://stackoverflow.com/questions/1264137/how-to-copy-string-to-clipboard-in-c or other platform-dependent implementation.

ocornut commented 5 years ago

You can use ImGui::SetClipboardText() to call in imgui’s own backend.

Dysotron commented 3 years ago

A workaround for this I've found is to use InputText with the readonly flag, like this:

                std::string inputId = "m_messages";
        inputId.append(std::to_string(i));
        char input[256];
        strcpy(input, m_messages[i].c_str());
        ImGui::PushID(inputId.c_str());
        ImGui::PushItemWidth(ImGui::GetWindowSize().x);
        ImGui::InputText("", input, 256, ImGuiInputTextFlags_ReadOnly);
        ImGui::PopItemWidth();
        ImGui::PopID();

That lets you highlight and copy the text

andrewmcdonald-oxb commented 2 years ago

Yes we've been using the InputText widget with ImGuiInputTextFlags_ReadOnly too, but it's awkward having to pass non-const char* in. Is there any interest in having a different signature with a const pointer, which could assert if the flag wasn't supplied?

ocornut commented 2 years ago

For now I'd prefer not adding extra signatures (as down the line that feature can be provided by a different widget or system), but you can add this signature + wrapper func in your source code.

geocine commented 2 years ago

Is there way to remove the background of the InputText so that it looks like a label at the same time want to use the Selectable() behavior for it? Has anyone done anything the same?

zubeyir-bodur commented 2 years ago

Yes, we can implement the feature with a different widget, but I dont think we can change the colours of the text we want in InputMultiLineText? It would be really nice to actually be able to select an arbitrary text (except clickables and window headers) of any window.

rokups commented 2 years ago

You can customize InputText() and InputTextMultiline() text color by modifying ImGuiCol_Text or ImGuiCol_TextDisabled (hint color) style colors.

zubeyir-bodur commented 2 years ago

You can customize InputText() and InputTextMultiline() text color by modifying ImGuiCol_Text or ImGuiCol_TextDisabled (hint color) style colors.

Thank you 😃. I actually needed to have different colors in the same InputTextMultiLine(), so I ended up changing the library on my own, but was still helpful to find where should I needed to change.

rokups commented 2 years ago

There is a library which already implements rich(er) text: https://github.com/BalazsJako/ImGuiColorTextEdit

zubeyir-bodur commented 2 years ago

There is a library which already implements rich(er) text: https://github.com/BalazsJako/ImGuiColorTextEdit

Thank you, I currently do not need an editable text, but might be really handy for a cool side project 😊

Green-Sky commented 1 year ago

since we are sharing code snippets, and I wanted a wrapping TextUnformated() that could be selected (and looks like normal text), here is mine:

ImGui::PushID(id++);
{
    ImVec2 text_size = ImGui::CalcTextSize(msgtext.c_str(), msgtext.c_str()+msgtext.size());
    text_size.x = -FLT_MIN; // fill width (suppresses label)
    text_size.y += ImGui::GetStyle().FramePadding.y; // single pad

    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); // make align with text height
    ImGui::PushStyleColor(ImGuiCol_FrameBg, {0.f, 0.f, 0.f, 0.f}); // remove text input box

    ImGui::InputTextMultiline(
        "",
        const_cast<char*>(msgtext.c_str()), // ugly const cast
        msgtext.size() + 1, // needs to include '\0'
        text_size,
        ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll
    );

    ImGui::PopStyleColor();
    ImGui::PopStyleVar();
}
ImGui::PopID();

it only uses public functions.

ocornut commented 1 year ago

Answering @sakiodre

While we're at this, what do you think we should do to implement highlightable/selectable text? https://github.com/ocornut/imgui/issues/950

I don't know yet, if I did part of the work would be done already :)

I haven't tackled this at all yet maybe it's actually easy. I expect it to be a rather low-level thing and needs to be optimal. I'm adding myself a note to experiment with a proof-of-concept which may influence V2 of text writing function.

ocornut commented 1 year ago

I am also closing #949 as essentially duplicate, see https://github.com/ocornut/imgui/issues/949#issue-197041941 and I've edited the second post to fix the gist link being https://gist.github.com/hb3p8/d97b7afe9e037339027121ff6c0eb6d9. This is similar to the ideas proposed here (submitting a InputText), but to be clear we inventually intend to support it at a lower-level and more automatically than that.

ocornut commented 8 months ago

Posted by @AidanSun05

I created a small text selection implementation as part of an open source app and extracted it under the MIT License: ImGuiTextSelect. I saw there were older discussions on this topic (https://github.com/ocornut/imgui/issues/950) and hope this can help some people.

Features include double/triple/shift-click selection, context menu integration, and UTF-8 support. Instructions for using it in a project are included in the linked repo. ImGuiTextSelect works well for text-only windows such as a console/log output or code display.

https://github.com/ocornut/imgui/assets/61399657/874c4dc0-6c10-42c0-a283-0db7117585af

(Adding to https://github.com/ocornut/imgui/wiki/Useful-Extensions)