| 9369 | } |
| 9370 | |
| 9371 | void ImGui::EndGroup() |
| 9372 | { |
| 9373 | ImGuiContext& g = *GImGui; |
| 9374 | ImGuiWindow* window = g.CurrentWindow; |
| 9375 | IM_ASSERT(g.GroupStack.Size > 0); // Mismatched BeginGroup()/EndGroup() calls |
| 9376 | |
| 9377 | ImGuiGroupData& group_data = g.GroupStack.back(); |
| 9378 | IM_ASSERT(group_data.WindowID == window->ID); // EndGroup() in wrong window? |
| 9379 | |
| 9380 | if (window->DC.IsSetPos) |
| 9381 | ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); |
| 9382 | |
| 9383 | ImRect group_bb(group_data.BackupCursorPos, ImMax(window->DC.CursorMaxPos, group_data.BackupCursorPos)); |
| 9384 | |
| 9385 | window->DC.CursorPos = group_data.BackupCursorPos; |
| 9386 | window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); |
| 9387 | window->DC.Indent = group_data.BackupIndent; |
| 9388 | window->DC.GroupOffset = group_data.BackupGroupOffset; |
| 9389 | window->DC.CurrLineSize = group_data.BackupCurrLineSize; |
| 9390 | window->DC.CurrLineTextBaseOffset = group_data.BackupCurrLineTextBaseOffset; |
| 9391 | if (g.LogEnabled) |
| 9392 | g.LogLinePosY = -FLT_MAX; // To enforce a carriage return |
| 9393 | |
| 9394 | if (!group_data.EmitItem) |
| 9395 | { |
| 9396 | g.GroupStack.pop_back(); |
| 9397 | return; |
| 9398 | } |
| 9399 | |
| 9400 | window->DC.CurrLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. |
| 9401 | ItemSize(group_bb.GetSize()); |
| 9402 | ItemAdd(group_bb, 0, NULL, ImGuiItemFlags_NoTabStop); |
| 9403 | |
| 9404 | // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive(), IsItemDeactivated() etc. will be functional on the entire group. |
| 9405 | // It would be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but would put a little more burden on individual widgets. |
| 9406 | // Also if you grep for LastItemId you'll notice it is only used in that context. |
| 9407 | // (The two tests not the same because ActiveIdIsAlive is an ID itself, in order to be able to handle ActiveId being overwritten during the frame.) |
| 9408 | const bool group_contains_curr_active_id = (group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId; |
| 9409 | const bool group_contains_prev_active_id = (group_data.BackupActiveIdPreviousFrameIsAlive == false) && (g.ActiveIdPreviousFrameIsAlive == true); |
| 9410 | if (group_contains_curr_active_id) |
| 9411 | g.LastItemData.ID = g.ActiveId; |
| 9412 | else if (group_contains_prev_active_id) |
| 9413 | g.LastItemData.ID = g.ActiveIdPreviousFrame; |
| 9414 | g.LastItemData.Rect = group_bb; |
| 9415 | |
| 9416 | // Forward Hovered flag |
| 9417 | const bool group_contains_curr_hovered_id = (group_data.BackupHoveredIdIsAlive == false) && g.HoveredId != 0; |
| 9418 | if (group_contains_curr_hovered_id) |
| 9419 | g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; |
| 9420 | |
| 9421 | // Forward Edited flag |
| 9422 | if (group_contains_curr_active_id && g.ActiveIdHasBeenEditedThisFrame) |
| 9423 | g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited; |
| 9424 | |
| 9425 | // Forward Deactivated flag |
| 9426 | g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDeactivated; |
| 9427 | if (group_contains_prev_active_id && g.ActiveId != g.ActiveIdPreviousFrame) |
| 9428 | g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Deactivated; |