mirror of
https://github.com/ocornut/imgui.git
synced 2026-04-19 14:00:54 +00:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_glfw.cpp # imgui.h
This commit is contained in:
@@ -653,6 +653,14 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
FocusWindow(window, ImGuiFocusRequestFlags_RestoreFocusedChild); // Still need to focus and bring to front, but try to avoid losing NavId when navigating a child
|
||||
}
|
||||
}
|
||||
if (flags & ImGuiButtonFlags_PressedOnRelease)
|
||||
{
|
||||
// FIXME: Traditionally ImGuiButtonFlags_PressedOnRelease never took ActiveId. Adding it in 2026-03-20 since ImGuiButtonFlags_NoHoldingActiveId can always be added.
|
||||
// We don't yet perform an explicit ClearActiveID() to reduce scope of change, but this possibility could be investigated.
|
||||
if (!(flags & ImGuiButtonFlags_NoHoldingActiveId))
|
||||
SetActiveID(id, window); // Hold on ID
|
||||
g.ActiveIdMouseButton = (ImS8)mouse_button_clicked;
|
||||
}
|
||||
}
|
||||
if (flags & ImGuiButtonFlags_PressedOnRelease)
|
||||
{
|
||||
@@ -3693,27 +3701,33 @@ int ImParseFormatPrecision(const char* fmt, int default_precision)
|
||||
}
|
||||
|
||||
// Create text input in place of another active widget (e.g. used when doing a Ctrl+Click on drag/slider widgets)
|
||||
// - This must be submitted right after the item it is overlaying.
|
||||
// FIXME: Facilitate using this in variety of other situations.
|
||||
// FIXME: Among other things, setting ImGuiItemFlags_AllowDuplicateId in LastItemData is currently correct but
|
||||
// the expected relationship between TempInputXXX functions and LastItemData is a little fishy.
|
||||
bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags)
|
||||
bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||
{
|
||||
// On the first frame, g.TempInputTextId == 0, then on subsequent frames it becomes == id.
|
||||
// We clear ActiveID on the first frame to allow the InputText() taking it back.
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
const bool init = (g.TempInputId != id);
|
||||
if (init)
|
||||
ClearActiveID();
|
||||
|
||||
g.CurrentWindow->DC.CursorPos = bb.Min;
|
||||
g.LastItemData.ItemFlags |= ImGuiItemFlags_AllowDuplicateId;
|
||||
bool value_changed = InputTextEx(label, NULL, buf, buf_size, bb.GetSize(), flags | ImGuiInputTextFlags_MergedItem);
|
||||
ImVec2 backup_pos = window->DC.CursorPos;
|
||||
window->DC.CursorPos = bb.Min;
|
||||
g.LastItemData.ItemFlags |= ImGuiItemFlags_AllowDuplicateId; // Using ImGuiInputTextFlags_MergedItem above will skip ItemAdd() so we poke here.
|
||||
bool value_changed = InputTextEx(label, NULL, buf, (int)buf_size, bb.GetSize(), flags | ImGuiInputTextFlags_TempInput | ImGuiInputTextFlags_AutoSelectAll, callback, user_data);
|
||||
KeepAliveID(id); // Not done because of ImGuiInputTextFlags_TempInput
|
||||
if (init)
|
||||
{
|
||||
// First frame we started displaying the InputText widget, we expect it to take the active id.
|
||||
IM_ASSERT(g.ActiveId == id);
|
||||
g.TempInputId = g.ActiveId;
|
||||
}
|
||||
if (g.ActiveId != id)
|
||||
g.TempInputId = 0;
|
||||
window->DC.CursorPos = backup_pos;
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@@ -4748,7 +4762,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Support for internal ImGuiInputTextFlags_MergedItem flag, which could be redesigned as an ItemFlags if needed (with test performed in ItemAdd)
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!(flags & ImGuiInputTextFlags_MergedItem))
|
||||
if (!(flags & ImGuiInputTextFlags_TempInput))
|
||||
if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable))
|
||||
return false;
|
||||
}
|
||||
@@ -4779,9 +4793,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (is_wordwrap)
|
||||
wrap_width = ImMax(1.0f, GetContentRegionAvail().x + (draw_window->ScrollbarY ? 0.0f : -g.Style.ScrollbarSize));
|
||||
|
||||
const bool user_clicked = hovered && io.MouseClicked[0];
|
||||
const bool input_requested_by_nav = (g.ActiveId != id) && (g.NavActivateId == id);
|
||||
const bool input_requested_by_reactivate = (g.InputTextReactivateId == id); // for io.ConfigInputTextEnterKeepActive
|
||||
const bool user_clicked = hovered && io.MouseClicked[0];
|
||||
const bool input_requested_by_user = (user_clicked) || (g.ActiveId == 0 && (flags & ImGuiInputTextFlags_TempInput));
|
||||
const ImGuiID scrollbar_id = (is_multiline && state != NULL) ? GetWindowScrollbarID(draw_window, ImGuiAxis_Y) : 0;
|
||||
const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == scrollbar_id;
|
||||
const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == scrollbar_id;
|
||||
@@ -4792,7 +4807,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
const bool init_reload_from_user_buf = (state != NULL && state->WantReloadUserBuf);
|
||||
const bool init_changed_specs = (state != NULL && state->Stb->single_line != !is_multiline); // state != NULL means its our state.
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav || input_requested_by_reactivate);
|
||||
const bool init_make_active = (input_requested_by_user || input_requested_by_nav || input_requested_by_reactivate || user_scroll_finish);
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
int new_len = (int)ImStrlen(buf);
|
||||
@@ -9257,11 +9272,12 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
PushID(label);
|
||||
if (!enabled)
|
||||
BeginDisabled();
|
||||
const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||
|
||||
bool pressed;
|
||||
|
||||
// We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another.
|
||||
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_NoAutoClosePopups;
|
||||
ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
{
|
||||
// Menu inside a horizontal menu bar
|
||||
@@ -9269,9 +9285,8 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
|
||||
window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f);
|
||||
PushStyleVarX(ImGuiStyleVar_ItemSpacing, style.ItemSpacing.x * 2.0f);
|
||||
float w = label_size.x;
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, label_size.y));
|
||||
pressed = Selectable("", menu_is_open, selectable_flags, label_size);
|
||||
LogSetNextTextDecoration("[", "]");
|
||||
RenderText(text_pos, label);
|
||||
PopStyleVar();
|
||||
@@ -9285,7 +9300,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.)
|
||||
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
|
||||
float min_w = offsets->DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
|
||||
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", menu_is_open, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y));
|
||||
@@ -9470,17 +9485,16 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
BeginDisabled();
|
||||
|
||||
// We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another.
|
||||
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SetNavIdOnHover;
|
||||
const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SetNavIdOnHover;
|
||||
ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
{
|
||||
// Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
|
||||
// Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark.
|
||||
float w = label_size.x;
|
||||
window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
PushStyleVarX(ImGuiStyleVar_ItemSpacing, style.ItemSpacing.x * 2.0f);
|
||||
pressed = Selectable("", selected, selectable_flags, ImVec2(w, 0.0f));
|
||||
pressed = Selectable("", selected, selectable_flags, ImVec2(label_size.x, 0.0f));
|
||||
PopStyleVar();
|
||||
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible)
|
||||
RenderText(text_pos, label);
|
||||
@@ -9494,7 +9508,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
||||
float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f;
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||
float min_w = offsets->DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
ImVec2 text_pos(pos.x, pos.y + window->DC.CurrLineTextBaseOffset);
|
||||
pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y));
|
||||
|
||||
Reference in New Issue
Block a user