Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional. Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
| 2388 | // Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional. |
| 2389 | // Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. |
| 2390 | bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) |
| 2391 | { |
| 2392 | ImGuiWindow* window = GetCurrentWindow(); |
| 2393 | if (window->SkipItems) |
| 2394 | return false; |
| 2395 | |
| 2396 | ImGuiContext& g = *GImGui; |
| 2397 | const ImGuiStyle& style = g.Style; |
| 2398 | const ImGuiID id = window->GetID(label); |
| 2399 | const float w = CalcItemWidth(); |
| 2400 | |
| 2401 | const ImVec2 label_size = CalcTextSize(label, NULL, true); |
| 2402 | const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); |
| 2403 | const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); |
| 2404 | |
| 2405 | const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0; |
| 2406 | ItemSize(total_bb, style.FramePadding.y); |
| 2407 | if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0)) |
| 2408 | return false; |
| 2409 | |
| 2410 | // Default format string when passing NULL |
| 2411 | if (format == NULL) |
| 2412 | format = DataTypeGetInfo(data_type)->PrintFmt; |
| 2413 | else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.) |
| 2414 | format = PatchFormatStringFloatToInt(format); |
| 2415 | |
| 2416 | // Tabbing or CTRL-clicking on Drag turns it into an InputText |
| 2417 | const bool hovered = ItemHoverable(frame_bb, id); |
| 2418 | bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); |
| 2419 | if (!temp_input_is_active) |
| 2420 | { |
| 2421 | const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; |
| 2422 | const bool clicked = (hovered && g.IO.MouseClicked[0]); |
| 2423 | const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2); |
| 2424 | if (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id) |
| 2425 | { |
| 2426 | SetActiveID(id, window); |
| 2427 | SetFocusID(id, window); |
| 2428 | FocusWindow(window); |
| 2429 | g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); |
| 2430 | if (temp_input_allowed) |
| 2431 | if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id) |
| 2432 | temp_input_is_active = true; |
| 2433 | } |
| 2434 | |
| 2435 | // Experimental: simple click (without moving) turns Drag into an InputText |
| 2436 | if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active) |
| 2437 | if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) |
| 2438 | { |
| 2439 | g.NavActivateId = g.NavActivateInputId = id; |
| 2440 | g.NavActivateFlags = ImGuiActivateFlags_PreferInput; |
| 2441 | temp_input_is_active = true; |
| 2442 | } |
| 2443 | } |
| 2444 | |
| 2445 | if (temp_input_is_active) |
| 2446 | { |
| 2447 | // Only clamp CTRL+Click input when ImGuiSliderFlags_AlwaysClamp is set |
nothing calls this directly
no test coverage detected