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.
| 2313 | // 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. |
| 2314 | // Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. |
| 2315 | 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) |
| 2316 | { |
| 2317 | ImGuiWindow* window = GetCurrentWindow(); |
| 2318 | if (window->SkipItems) |
| 2319 | return false; |
| 2320 | |
| 2321 | ImGuiContext& g = *GImGui; |
| 2322 | const ImGuiStyle& style = g.Style; |
| 2323 | const ImGuiID id = window->GetID(label); |
| 2324 | const float w = CalcItemWidth(); |
| 2325 | |
| 2326 | const ImVec2 label_size = CalcTextSize(label, NULL, true); |
| 2327 | const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); |
| 2328 | 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)); |
| 2329 | |
| 2330 | const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0; |
| 2331 | ItemSize(total_bb, style.FramePadding.y); |
| 2332 | if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0)) |
| 2333 | return false; |
| 2334 | |
| 2335 | // Default format string when passing NULL |
| 2336 | if (format == NULL) |
| 2337 | format = DataTypeGetInfo(data_type)->PrintFmt; |
| 2338 | |
| 2339 | const bool hovered = ItemHoverable(frame_bb, id); |
| 2340 | bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); |
| 2341 | if (!temp_input_is_active) |
| 2342 | { |
| 2343 | // Tabbing or CTRL-clicking on Drag turns it into an InputText |
| 2344 | const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; |
| 2345 | const bool clicked = hovered && IsMouseClicked(0, id); |
| 2346 | const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id)); |
| 2347 | const bool make_active = (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id); |
| 2348 | if (make_active && (clicked || double_clicked)) |
| 2349 | SetKeyOwner(ImGuiKey_MouseLeft, id); |
| 2350 | if (make_active && temp_input_allowed) |
| 2351 | if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id) |
| 2352 | temp_input_is_active = true; |
| 2353 | |
| 2354 | // (Optional) simple click (without moving) turns Drag into an InputText |
| 2355 | if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active) |
| 2356 | if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) |
| 2357 | { |
| 2358 | g.NavActivateId = g.NavActivateInputId = id; |
| 2359 | g.NavActivateFlags = ImGuiActivateFlags_PreferInput; |
| 2360 | temp_input_is_active = true; |
| 2361 | } |
| 2362 | |
| 2363 | if (make_active && !temp_input_is_active) |
| 2364 | { |
| 2365 | SetActiveID(id, window); |
| 2366 | SetFocusID(id, window); |
| 2367 | FocusWindow(window); |
| 2368 | g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); |
| 2369 | } |
| 2370 | } |
| 2371 | |
| 2372 | if (temp_input_is_active) |
nothing calls this directly
no test coverage detected