mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 13:11:05 +01:00 
			
		
		
		
	Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_opengl3.cpp # imgui.cpp # imgui.h # imgui_demo.cpp
This commit is contained in:
		| @@ -1450,6 +1450,8 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float | ||||
|     ImRect bb_interact = bb; | ||||
|     bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); | ||||
|     ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); | ||||
|     if (hovered) | ||||
|         window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredRect; // for IsItemHovered(), because bb_interact is larger than bb | ||||
|     if (g.ActiveId != id) | ||||
|         SetItemAllowOverlap(); | ||||
|  | ||||
| @@ -1547,6 +1549,8 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc | ||||
| // - BeginCombo() | ||||
| // - BeginComboPopup() [Internal] | ||||
| // - EndCombo() | ||||
| // - BeginComboPreview() [Internal] | ||||
| // - EndComboPreview() [Internal] | ||||
| // - Combo() | ||||
| //------------------------------------------------------------------------- | ||||
|  | ||||
| @@ -1608,6 +1612,14 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF | ||||
|     } | ||||
|     RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); | ||||
|  | ||||
|     // Custom preview | ||||
|     if (flags & ImGuiComboFlags_CustomPreview) | ||||
|     { | ||||
|         g.ComboPreviewData.PreviewRect = ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y); | ||||
|         IM_ASSERT(preview_value == NULL || preview_value[0] == 0); | ||||
|         preview_value = NULL; | ||||
|     } | ||||
|  | ||||
|     // Render preview and label | ||||
|     if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview)) | ||||
|     { | ||||
| @@ -1689,6 +1701,57 @@ void ImGui::EndCombo() | ||||
|     EndPopup(); | ||||
| } | ||||
|  | ||||
| // Call directly after the BeginCombo/EndCombo block. The preview is designed to only host non-interactive elements | ||||
| // (Experimental, see GitHub issues: #1658, #4168) | ||||
| bool ImGui::BeginComboPreview() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     ImGuiComboPreviewData* preview_data = &g.ComboPreviewData; | ||||
|  | ||||
|     if (window->SkipItems || !window->ClipRect.Overlaps(window->DC.LastItemRect)) // FIXME: Because we don't have a ImGuiItemStatusFlags_Visible flag to test last ItemAdd() result | ||||
|         return false; | ||||
|     IM_ASSERT(window->DC.LastItemRect.Min.x == preview_data->PreviewRect.Min.x && window->DC.LastItemRect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag? | ||||
|     if (!window->ClipRect.Contains(preview_data->PreviewRect)) // Narrower test (optional) | ||||
|         return false; | ||||
|  | ||||
|     // FIXME: This could be contained in a PushWorkRect() api | ||||
|     preview_data->BackupCursorPos = window->DC.CursorPos; | ||||
|     preview_data->BackupCursorMaxPos = window->DC.CursorMaxPos; | ||||
|     preview_data->BackupCursorPosPrevLine = window->DC.CursorPosPrevLine; | ||||
|     preview_data->BackupPrevLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; | ||||
|     preview_data->BackupLayout = window->DC.LayoutType; | ||||
|     window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding; | ||||
|     window->DC.CursorMaxPos = window->DC.CursorPos; | ||||
|     window->DC.LayoutType = ImGuiLayoutType_Horizontal; | ||||
|     PushClipRect(preview_data->PreviewRect.Min, preview_data->PreviewRect.Max, true); | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| void ImGui::EndComboPreview() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     ImGuiComboPreviewData* preview_data = &g.ComboPreviewData; | ||||
|  | ||||
|     // FIXME: Using CursorMaxPos approximation instead of correct AABB which we will store in ImDrawCmd in the future | ||||
|     ImDrawList* draw_list = window->DrawList; | ||||
|     if (window->DC.CursorMaxPos.x < preview_data->PreviewRect.Max.x && window->DC.CursorMaxPos.y < preview_data->PreviewRect.Max.y) | ||||
|         if (draw_list->CmdBuffer.Size > 1) // Unlikely case that the PushClipRect() didn't create a command | ||||
|         { | ||||
|             draw_list->_CmdHeader.ClipRect = draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ClipRect = draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 2].ClipRect; | ||||
|             draw_list->_TryMergeDrawCmds(); | ||||
|         } | ||||
|     PopClipRect(); | ||||
|     window->DC.CursorPos = preview_data->BackupCursorPos; | ||||
|     window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, preview_data->BackupCursorMaxPos); | ||||
|     window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine; | ||||
|     window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset; | ||||
|     window->DC.LayoutType = preview_data->BackupLayout; | ||||
|     preview_data->PreviewRect = ImRect(); | ||||
| } | ||||
|  | ||||
| // Getter for the old Combo() API: const char*[] | ||||
| static bool Items_ArrayGetter(void* data, int idx, const char** out_text) | ||||
| { | ||||
| @@ -5889,8 +5952,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l | ||||
|         { | ||||
|             const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); | ||||
|             RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, false); | ||||
|             RenderNavHighlight(frame_bb, id, nav_highlight_flags); | ||||
|         } | ||||
|         RenderNavHighlight(frame_bb, id, nav_highlight_flags); | ||||
|         if (flags & ImGuiTreeNodeFlags_Bullet) | ||||
|             RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col); | ||||
|         else if (!is_leaf) | ||||
| @@ -6127,6 +6190,17 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl | ||||
|     bool hovered, held; | ||||
|     bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags); | ||||
|  | ||||
|     // Auto-select when moved into | ||||
|     // - This will be more fully fleshed in the range-select branch | ||||
|     // - This is not exposed as it won't nicely work with some user side handling of shift/control | ||||
|     // - We cannot do 'if (g.NavJustMovedToId != id) { selected = false; pressed = was_selected; }' for two reasons | ||||
|     //   - (1) it would require focus scope to be set, need exposing PushFocusScope() or equivalent (e.g. BeginSelection() calling PushFocusScope()) | ||||
|     //   - (2) usage will fail with clipped items | ||||
|     //   The multi-select API aim to fix those issues, e.g. may be replaced with a BeginSelection() API. | ||||
|     if ((flags & ImGuiSelectableFlags_SelectOnNav) && g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == window->DC.NavFocusScopeIdCurrent) | ||||
|         if (g.NavJustMovedToId == id) | ||||
|             selected = pressed = true; | ||||
|  | ||||
|     // Update NavId when clicking or when Hovering (this doesn't happen on most widgets), so navigation can be resumed with gamepad/keyboard | ||||
|     if (pressed || (hovered && (flags & ImGuiSelectableFlags_SetNavIdOnHover))) | ||||
|     { | ||||
| @@ -6153,8 +6227,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl | ||||
|     { | ||||
|         const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); | ||||
|         RenderFrame(bb.Min, bb.Max, col, false, 0.0f); | ||||
|         RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); | ||||
|     } | ||||
|     RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); | ||||
|  | ||||
|     if (span_all_columns && window->DC.CurrentColumns) | ||||
|         PopColumnsBackground(); | ||||
| @@ -8138,14 +8212,7 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, | ||||
| #endif | ||||
|  | ||||
|     // Render text label (with clipping + alpha gradient) + unsaved marker | ||||
|     const char* TAB_UNSAVED_MARKER = "*"; | ||||
|     ImRect text_pixel_clip_bb(bb.Min.x + frame_padding.x, bb.Min.y + frame_padding.y, bb.Max.x - frame_padding.x, bb.Max.y); | ||||
|     if (flags & ImGuiTabItemFlags_UnsavedDocument) | ||||
|     { | ||||
|         text_pixel_clip_bb.Max.x -= CalcTextSize(TAB_UNSAVED_MARKER, NULL, false).x; | ||||
|         ImVec2 unsaved_marker_pos(ImMin(bb.Min.x + frame_padding.x + label_size.x + 2, text_pixel_clip_bb.Max.x), bb.Min.y + frame_padding.y + IM_FLOOR(-g.FontSize * 0.25f)); | ||||
|         RenderTextClippedEx(draw_list, unsaved_marker_pos, bb.Max - frame_padding, TAB_UNSAVED_MARKER, NULL, NULL); | ||||
|     } | ||||
|     ImRect text_ellipsis_clip_bb = text_pixel_clip_bb; | ||||
|  | ||||
|     // Return clipped state ignoring the close button | ||||
| @@ -8155,7 +8222,10 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, | ||||
|         //draw_list->AddCircle(text_ellipsis_clip_bb.Min, 3.0f, *out_text_clipped ? IM_COL32(255, 0, 0, 255) : IM_COL32(0, 255, 0, 255)); | ||||
|     } | ||||
|  | ||||
|     // Close Button | ||||
|     const float button_sz = g.FontSize; | ||||
|     const ImVec2 button_pos(ImMax(bb.Min.x, bb.Max.x - frame_padding.x * 2.0f - button_sz), bb.Min.y); | ||||
|  | ||||
|     // Close Button & Unsaved Marker | ||||
|     // We are relying on a subtle and confusing distinction between 'hovered' and 'g.HoveredId' which happens because we are using ImGuiButtonFlags_AllowOverlapMode + SetItemAllowOverlap() | ||||
|     //  'hovered' will be true when hovering the Tab but NOT when hovering the close button | ||||
|     //  'g.HoveredId==id' will be true when hovering the Tab including when hovering the close button | ||||
| @@ -8163,15 +8233,16 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, | ||||
|     bool close_button_pressed = false; | ||||
|     bool close_button_visible = false; | ||||
|     if (close_button_id != 0) | ||||
|         if (is_contents_visible || bb.GetWidth() >= g.Style.TabMinWidthForCloseButton) | ||||
|         if (is_contents_visible || bb.GetWidth() >= ImMax(button_sz, g.Style.TabMinWidthForCloseButton)) | ||||
|             if (g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id) | ||||
|                 close_button_visible = true; | ||||
|     bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x); | ||||
|  | ||||
|     if (close_button_visible) | ||||
|     { | ||||
|         ImGuiLastItemDataBackup last_item_backup; | ||||
|         const float close_button_sz = g.FontSize; | ||||
|         PushStyleVar(ImGuiStyleVar_FramePadding, frame_padding); | ||||
|         if (CloseButton(close_button_id, ImVec2(bb.Max.x - frame_padding.x * 2.0f - close_button_sz, bb.Min.y))) | ||||
|         if (CloseButton(close_button_id, button_pos)) | ||||
|             close_button_pressed = true; | ||||
|         PopStyleVar(); | ||||
|         last_item_backup.Restore(); | ||||
| @@ -8179,12 +8250,23 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, | ||||
|         // Close with middle mouse button | ||||
|         if (!(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2)) | ||||
|             close_button_pressed = true; | ||||
|  | ||||
|         text_pixel_clip_bb.Max.x -= close_button_sz; | ||||
|     } | ||||
|     else if (unsaved_marker_visible) | ||||
|     { | ||||
|         const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz) + g.Style.FramePadding * 2.0f); | ||||
|         RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text)); | ||||
|     } | ||||
|  | ||||
|     // This is all rather complicated | ||||
|     // (the main idea is that because the close button only appears on hover, we don't want it to alter the ellipsis position) | ||||
|     // FIXME: if FramePadding is noticeably large, ellipsis_max_x will be wrong here (e.g. #3497), maybe for consistency that parameter of RenderTextEllipsis() shouldn't exist.. | ||||
|     float ellipsis_max_x = close_button_visible ? text_pixel_clip_bb.Max.x : bb.Max.x - 1.0f; | ||||
|     if (close_button_visible || unsaved_marker_visible) | ||||
|     { | ||||
|         text_pixel_clip_bb.Max.x -= close_button_visible ? (button_sz) : (button_sz * 0.80f); | ||||
|         text_ellipsis_clip_bb.Max.x -= unsaved_marker_visible ? (button_sz * 0.80f) : 0.0f; | ||||
|         ellipsis_max_x = text_pixel_clip_bb.Max.x; | ||||
|     } | ||||
|     RenderTextEllipsis(draw_list, text_ellipsis_clip_bb.Min, text_ellipsis_clip_bb.Max, text_pixel_clip_bb.Max.x, ellipsis_max_x, label, NULL, &label_size); | ||||
|  | ||||
| #if 0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user