mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Combo() now using the popup facility. More consistent + when combo open hovering other widgets is disabled. (#241)
This commit is contained in:
parent
6f1dd7a688
commit
8c86322068
64
imgui.cpp
64
imgui.cpp
@ -1301,7 +1301,6 @@ struct ImGuiState
|
||||
ImGuiTextEditState InputTextState;
|
||||
ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
|
||||
ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode
|
||||
ImGuiID ActiveComboID;
|
||||
ImVec2 ActiveClickDeltaToCenter;
|
||||
float DragCurrentValue; // current dragged value, always float, not rounded by end-user precision settings
|
||||
ImVec2 DragLastMouseDelta;
|
||||
@ -1362,7 +1361,6 @@ struct ImGuiState
|
||||
SetNextTreeNodeOpenedCond = 0;
|
||||
|
||||
ScalarAsInputTextId = 0;
|
||||
ActiveComboID = 0;
|
||||
ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f);
|
||||
DragCurrentValue = 0.0f;
|
||||
DragLastMouseDelta = ImVec2(0.0f, 0.0f);
|
||||
@ -3126,6 +3124,14 @@ static void ClosePopupToLevel(int remaining)
|
||||
g.OpenedPopupStack.resize(remaining);
|
||||
}
|
||||
|
||||
static void ClosePopup(ImGuiID id)
|
||||
{
|
||||
if (!IsPopupOpen(id))
|
||||
return;
|
||||
ImGuiState& g = *GImGui;
|
||||
ClosePopupToLevel(g.OpenedPopupStack.size() - 1);
|
||||
}
|
||||
|
||||
// Close the popup we have begin-ed into.
|
||||
void ImGui::CloseCurrentPopup()
|
||||
{
|
||||
@ -3156,7 +3162,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_ShowBorders|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize;
|
||||
ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize;
|
||||
|
||||
char name[32];
|
||||
if (flags & ImGuiWindowFlags_ChildMenu)
|
||||
@ -3176,7 +3182,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
|
||||
|
||||
bool ImGui::BeginPopup(const char* str_id)
|
||||
{
|
||||
return BeginPopupEx(str_id, 0);
|
||||
return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders);
|
||||
}
|
||||
|
||||
void ImGui::EndPopup()
|
||||
@ -7288,7 +7294,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char** items, int
|
||||
bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items)
|
||||
{
|
||||
int items_count = 0;
|
||||
const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this
|
||||
const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open
|
||||
while (*p)
|
||||
{
|
||||
p += strlen(p) + 1;
|
||||
@ -7320,7 +7326,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
||||
const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f);
|
||||
const bool hovered = IsHovered(frame_bb, id);
|
||||
|
||||
bool value_changed = false;
|
||||
const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING
|
||||
@ -7336,42 +7341,45 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
||||
if (label_size.x > 0)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
ImGui::PushID((int)id);
|
||||
bool menu_toggled = false;
|
||||
if (hovered)
|
||||
{
|
||||
g.HoveredId = id;
|
||||
if (g.IO.MouseClicked[0])
|
||||
{
|
||||
menu_toggled = true;
|
||||
SetActiveId(0);
|
||||
g.ActiveComboID = (g.ActiveComboID == id) ? 0 : id;
|
||||
if (g.ActiveComboID)
|
||||
if (IsPopupOpen(id))
|
||||
{
|
||||
ClosePopup(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
FocusWindow(window);
|
||||
ImGui::OpenPopup(label);
|
||||
menu_toggled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g.ActiveComboID == id)
|
||||
bool value_changed = false;
|
||||
if (IsPopupOpen(id))
|
||||
{
|
||||
// Size default to hold ~7 items
|
||||
if (height_in_items < 0)
|
||||
height_in_items = 7;
|
||||
|
||||
const ImVec2 backup_pos = ImGui::GetCursorPos();
|
||||
const float popup_off_x = 0.0f;//style.ItemInnerSpacing.x;
|
||||
const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3);
|
||||
const ImRect popup_rect(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height));
|
||||
ImGui::SetCursorPos(popup_rect.Min - window->Pos);
|
||||
const ImRect popup_rect(ImVec2(frame_bb.Min.x, frame_bb.Max.y), ImVec2(frame_bb.Max.x, frame_bb.Max.y + popup_height));
|
||||
ImGui::SetNextWindowPos(popup_rect.Min);
|
||||
ImGui::SetNextWindowSize(popup_rect.GetSize());
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
|
||||
|
||||
const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
|
||||
ImGui::BeginChild("#ComboBox", popup_rect.GetSize(), false, flags);
|
||||
ImGui::Spacing();
|
||||
|
||||
bool combo_item_active = false;
|
||||
combo_item_active |= (g.ActiveId == GetCurrentWindow()->GetID("#SCROLLY"));
|
||||
|
||||
if (BeginPopupEx(label, flags))
|
||||
{
|
||||
// Display items
|
||||
ImGui::Spacing();
|
||||
for (int i = 0; i < items_count; i++)
|
||||
{
|
||||
ImGui::PushID((void*)(intptr_t)i);
|
||||
@ -7382,25 +7390,17 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
||||
if (ImGui::Selectable(item_text, item_selected))
|
||||
{
|
||||
SetActiveId(0);
|
||||
g.ActiveComboID = 0;
|
||||
value_changed = true;
|
||||
*current_item = i;
|
||||
}
|
||||
if (item_selected && menu_toggled)
|
||||
ImGui::SetScrollPosHere();
|
||||
combo_item_active |= ImGui::IsItemActive();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::SetCursorPos(backup_pos);
|
||||
|
||||
if (!combo_item_active && g.ActiveId != 0)
|
||||
g.ActiveComboID = 0;
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@ -7769,7 +7769,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
if (opened)
|
||||
{
|
||||
ImGui::SetNextWindowPos(popup_pos, ImGuiSetCond_Always);
|
||||
ImGuiWindowFlags flags = (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu;
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu);
|
||||
opened = BeginPopupEx(label, flags); // opened can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user