#include "my_imgui_internal_widgets.h" #include "imgui.h" #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS #endif #include "imgui_internal.h" // A modded version of ScalarSlider allowing for the minimum and maximum parts // of the slider to be draggable by two other buttons. p_mid is from range -1 // to 1, and s_min and max are from 0-1. bool ImGui::SliderLevels(const char* label, void* p_mid, void* p_left, void* p_right) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; const float SliderMin = -1; const float SliderMax = 1; const float OtherMin = 0; const float OtherMax = 1; const void* p_min = &SliderMin; const void* p_max = &SliderMax; const void* o_min = &OtherMin; const void* o_max = &OtherMax; ImGuiDataType data_type = ImGuiDataType_Float; const char *format = "%f"; ImGuiSliderFlags flags = ImGuiSliderFlags_NoInput; ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; // I'm not well-versed in exactly what ImGui's id system does, but I'm // pretty sure it's one clickable object equals one ImGui ID. const ImGuiID id = window->GetID(label); PushID(label); PushID(1); const ImGuiID id_L = window->GetID(""); PopID(); PopID(); const ImGuiID id_R = window->GetID("adsafb"); const ImGuiID id_mid = window->GetID("asdasbdsgd"); const float w = CalcItemWidth(); const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); 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)); ItemSize(total_bb, style.FramePadding.y); if (!ItemAdd(total_bb, id_L, &frame_bb, 0)) return false; if (!ItemAdd(total_bb, id_R, &frame_bb, 0)) return false; if (!ItemAdd(total_bb, id_mid, &frame_bb, 0)) return false; // Slider behavior ImRect grab_bb; const bool value_changed = SliderBehavior(frame_bb, id_L, data_type, p_left, o_min, o_max, format, flags, &grab_bb); if (value_changed) MarkItemEdited(id_L); ImRect grab_bb2; const bool value_changed2 = SliderBehavior(frame_bb, id_R, data_type, p_right, o_min, o_max, format, flags, &grab_bb2); if (value_changed2) MarkItemEdited(id_R); const ImRect mid_bb(ImVec2(grab_bb.Max.x, frame_bb.Min.y), ImVec2(grab_bb2.Min.x, frame_bb.Max.y)); // Slider behavior ImRect grab_bb3; const bool value_changed3 = SliderBehavior(mid_bb, id_mid, data_type, p_mid, p_min, p_max, format, flags, &grab_bb3); if (value_changed3) MarkItemEdited(id_mid); const bool hovered = ItemHoverable(frame_bb, id); const bool input_requested_by_tabbing = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; const bool clicked = (hovered && g.IO.MouseClicked[0]); const bool make_active = (input_requested_by_tabbing || clicked || g.NavActivateId == id || g.NavActivateInputId == id); if (make_active) { if (g.IO.MousePos.x < grab_bb.Max.x) { SetActiveID(id_L, window); SetFocusID(id_L, window); } else if (g.IO.MousePos.x > grab_bb2.Min.x) { SetActiveID(id_R, window); SetFocusID(id_R, window); } else { SetActiveID(id_mid, window); SetFocusID(id_mid, window); } FocusWindow(window); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); } // Draw frame const ImU32 frame_col = GetColorU32(g.ActiveId == id_L ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); RenderNavHighlight(frame_bb, id_L); RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding); // Render grab if (grab_bb.Max.x > grab_bb.Min.x) window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id_L ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); // Render grab if (grab_bb2.Max.x > grab_bb2.Min.x) window->DrawList->AddRectFilled(grab_bb2.Min, grab_bb2.Max, GetColorU32(g.ActiveId == id_R ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); // Render grab if (grab_bb3.Max.x > grab_bb3.Min.x) window->DrawList->AddRectFilled(grab_bb3.Min, grab_bb3.Max, GetColorU32(g.ActiveId == id_mid ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. char value_buf[64]; const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_left, format); if (g.LogEnabled) LogSetNextTextDecoration("{", "}"); RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); if (label_size.x > 0.0f) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); return value_changed; }