Selectable() added flags ImGuiSelectableFlags_DontClosePopups , ImGuiSelectableFlags_SpanAllColumns (#125)

This commit is contained in:
ocornut 2015-06-14 12:41:40 -06:00
parent 2bcafc861e
commit cf481e1a7b
2 changed files with 51 additions and 28 deletions

View File

@ -518,7 +518,6 @@ struct ImGuiState;
struct ImGuiWindow; struct ImGuiWindow;
typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ typedef int ImGuiLayoutType; // enum ImGuiLayoutType_
typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_
typedef int ImGuiSelectableFlags; // enum ImGuiSelectableFlags_
static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, ImGuiButtonFlags flags = 0); static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, ImGuiButtonFlags flags = 0);
static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL);
@ -979,19 +978,19 @@ enum ImGuiLayoutType_
enum ImGuiButtonFlags_ enum ImGuiButtonFlags_
{ {
ImGuiButtonFlags_Repeat = (1 << 0), ImGuiButtonFlags_Repeat = 1 << 0,
ImGuiButtonFlags_PressedOnClick = (1 << 1), ImGuiButtonFlags_PressedOnClick = 1 << 1,
ImGuiButtonFlags_FlattenChilds = (1 << 2), ImGuiButtonFlags_FlattenChilds = 1 << 2,
ImGuiButtonFlags_DontClosePopups = (1 << 3), ImGuiButtonFlags_DontClosePopups = 1 << 3,
ImGuiButtonFlags_Disabled = (1 << 4) ImGuiButtonFlags_Disabled = 1 << 4
}; };
enum ImGuiSelectableFlags_ enum ImGuiSelectableFlagsPrivate_
{ {
ImGuiSelectableFlags_MenuItem = (1 << 0), // NB: need to be in sync with last value of ImGuiSelectableFlags_
ImGuiSelectableFlags_DontClosePopups = (1 << 1), ImGuiSelectableFlags_MenuItem = 1 << 2,
ImGuiSelectableFlags_Disabled = (1 << 2), ImGuiSelectableFlags_Disabled = 1 << 3,
ImGuiSelectableFlags_DrawFillAvailWidth = (1 << 3) ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 4
}; };
@ -7407,13 +7406,18 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
return value_changed; return value_changed;
} }
static bool SelectableEx(const char* label, bool selected, const ImVec2& size_arg, ImGuiSelectableFlags flags) // Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image.
// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID.
bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg, ImGuiSelectableFlags flags)
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
return false; return false;
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
PopClipRect();
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
ImGuiID id = window->GetID(label); ImGuiID id = window->GetID(label);
ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
@ -7425,7 +7429,8 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
// Fill horizontal space. // Fill horizontal space.
ImVec2 window_padding = window->WindowPadding(); ImVec2 window_padding = window->WindowPadding();
float w_draw = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - window_padding.x - window->DC.CursorPos.x); float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? ImGui::GetWindowContentRegionMax().x : ImGui::GetContentRegionMax().x;
float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x);
ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y); ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y);
ImRect bb_with_spacing(pos, pos + size_draw); ImRect bb_with_spacing(pos, pos + size_draw);
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth))
@ -7441,7 +7446,11 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
bb_with_spacing.Max.x += spacing_R; bb_with_spacing.Max.x += spacing_R;
bb_with_spacing.Max.y += spacing_D; bb_with_spacing.Max.y += spacing_D;
if (!ItemAdd(bb_with_spacing, &id)) if (!ItemAdd(bb_with_spacing, &id))
{
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
PushColumnClipRect();
return false; return false;
}
bool hovered, held; bool hovered, held;
bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, ((flags & ImGuiSelectableFlags_MenuItem) ? ImGuiButtonFlags_PressedOnClick : 0) | ((flags & ImGuiSelectableFlags_Disabled) ? ImGuiButtonFlags_Disabled : 0)); bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, ((flags & ImGuiSelectableFlags_MenuItem) ? ImGuiButtonFlags_PressedOnClick : 0) | ((flags & ImGuiSelectableFlags_Disabled) ? ImGuiButtonFlags_Disabled : 0));
@ -7454,6 +7463,13 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f); RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f);
} }
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
{
PushColumnClipRect();
bb_with_spacing.Max.x -= (ImGui::GetContentRegionMax().x - max_x);
}
if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size); RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size);
if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor(); if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor();
@ -7464,16 +7480,9 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
return pressed; return pressed;
} }
// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg, ImGuiSelectableFlags flags)
// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID.
bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg)
{ {
return SelectableEx(label, selected, size_arg, 0); if (ImGui::Selectable(label, *p_selected, size_arg, flags))
}
bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg)
{
if (SelectableEx(label, *p_selected, size_arg, 0))
{ {
*p_selected = !*p_selected; *p_selected = !*p_selected;
return true; return true;
@ -7589,7 +7598,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame
float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
bool pressed = SelectableEx(label, false, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); bool pressed = ImGui::Selectable(label, false, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0));
if (shortcut_size.x > 0.0f) if (shortcut_size.x > 0.0f)
{ {
ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
@ -7702,7 +7711,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f);
float w = label_size.x; float w = label_size.x;
pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); pressed = ImGui::Selectable(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0));
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::SameLine(); ImGui::SameLine();
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
@ -7712,7 +7721,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame
float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); pressed = ImGui::Selectable(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0));
if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false); RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false);
if (!enabled) ImGui::PopStyleColor(); if (!enabled) ImGui::PopStyleColor();
@ -11226,9 +11235,14 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::Separator(); ImGui::Separator();
const char* names[3] = { "One", "Two", "Three" }; const char* names[3] = { "One", "Two", "Three" };
const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
static int selected = -1;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
ImGui::Text("%04d", i); ImGui::NextColumn(); char label[32];
sprintf(label, "%04d", i);
if (ImGui::Selectable(label, selected == i, ImVec2(0,0), ImGuiSelectableFlags_SpanAllColumns))
selected = i;
ImGui::NextColumn();
ImGui::Text(names[i]); ImGui::NextColumn(); ImGui::Text(names[i]); ImGui::NextColumn();
ImGui::Text(paths[i]); ImGui::NextColumn(); ImGui::Text(paths[i]); ImGui::NextColumn();
ImGui::Text("...."); ImGui::NextColumn(); ImGui::Text("...."); ImGui::NextColumn();

13
imgui.h
View File

@ -48,6 +48,7 @@ typedef int ImGuiMouseCursor; // enum ImGuiMouseCursor_
typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_ typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_
typedef int ImGuiSetCond; // enum ImGuiSetCond_ typedef int ImGuiSetCond; // enum ImGuiSetCond_
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_ typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
typedef int ImGuiSelectableFlags; // enum ImGuiSelectableFlags_
struct ImGuiTextEditCallbackData; // for advanced uses of InputText() struct ImGuiTextEditCallbackData; // for advanced uses of InputText()
typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
@ -300,8 +301,8 @@ namespace ImGui
IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened.
// Widgets: Selectable / Lists // Widgets: Selectable / Lists
IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0)); IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0);
IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0)); IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0);
IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards.
@ -443,6 +444,14 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_CallbackCharFilter = 1 << 9 // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. ImGuiInputTextFlags_CallbackCharFilter = 1 << 9 // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character.
}; };
// Flags for ImGui::Selectable()
enum ImGuiSelectableFlags_
{
// Default: 0
ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window
ImGuiSelectableFlags_SpanAllColumns = 1 << 1 // Selectable frame spans all columns (text will still fit in current column)
};
// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
enum ImGuiKey_ enum ImGuiKey_
{ {