mostly finished toggle + sliders

This commit is contained in:
yhqe committed 2026-03-27 00:30:28 -05:00
1 parent 6c17fd9b2f
commit 00a6b4d54e
2 files changed
+221 -29

No files matched your search

+123 -3
View File
@@ -14,6 +14,10 @@
#include <tchar.h>
#include <misc/freetype/imgui_freetype.h>
#include <string>
#include <vector>
#include <cmath>
#include "imgui_internal.h"
#include "fonts/montserrat.c"
// Data
@@ -24,6 +28,8 @@ static bool g_SwapChainOccluded = false;
static UINT g_ResizeWidth = 0, g_ResizeHeight = 0;
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;
#define IM_PI 3.14159265358979323846f
// Forward declarations of helper functions
bool CreateDeviceD3D(HWND hWnd);
void CleanupDeviceD3D();
@@ -31,6 +37,24 @@ void CreateRenderTarget();
void CleanupRenderTarget();
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void draw_star(ImVec2 center, float outerRadius, float innerRadius, int numPoints, ImU32 color, float rotation)
{
ImDrawList* drawList = ImGui::GetWindowDrawList();
int totalPoints = numPoints * 2;
for (int i = 0; i < totalPoints; i++)
{
float angle = rotation + ((float)i / totalPoints) * 2.0f * IM_PI - (IM_PI / 2.0f);
float radius = (i % 2 == 0) ? outerRadius : innerRadius;
drawList->PathLineTo(ImVec2(
center.x + cosf(angle) * radius,
center.y + sinf(angle) * radius
));
}
drawList->PathFillConcave(color);
}
// Main code
int main(int, char**)
{
@@ -78,6 +102,10 @@ int main(int, char**)
// Our state
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
bool test_bool = false;
float test_float = 0.f;
int test_int = 0;
// Main loop
bool done = false;
while (!done)
@@ -133,7 +161,7 @@ int main(int, char**)
auto draw = ImGui::GetWindowDrawList();
auto b_draw = ImGui::GetBackgroundDrawList();
const int shadow_layers = 10;
/*const int shadow_layers = 10;
const float shadow_size = 5.0f;
for (int i = 0; i < shadow_layers; ++i)
{
@@ -146,13 +174,13 @@ int main(int, char**)
IM_COL32(40, 46, 60, alpha),
10.0f + expand
);
}
}*/
draw->AddRectFilled(ImGui::GetWindowPos(), ImGui::GetWindowPos() + ImGui::GetWindowSize(), IM_COL32(40, 46, 60, 255), 10.f);
// titlebar
{
const float title_h = 30.0f;
const float title_r = 10.0f;
const float title_r = 8.f;
const ImU32 col_l = IM_COL32(129, 183, 255, 255);
const ImU32 col_r = IM_COL32(137, 120, 255, 255);
@@ -171,6 +199,89 @@ int main(int, char**)
draw->AddCircleFilled(ImVec2(pos.x + title_r, pos.y + title_r), title_r, col_l, 24);
draw->AddCircleFilled(ImVec2(pos.x + size.x - title_r, pos.y + title_r), title_r, col_r, 24);
const float t = static_cast<float>(ImGui::GetTime());
const int segments = 80;
const float amp = 3.5f;
const float freq = 6.0f;
const float phase_step = 0.8f;
ImU32 wave_color = IM_COL32(180, 200, 255, 140);
for (int l = 0; l < 3; ++l)
{
float y_base = pos.y + title_h * 0.55f + l * 3.5f;
draw->PathClear();
for (int i = 0; i <= segments; ++i)
{
float u = static_cast<float>(i) / static_cast<float>(segments);
float x = pos.x + (size.x) * u;
float y = y_base + std::sinf(u * freq + t * 2.2f + l * phase_step) * amp;
draw->PathLineTo(ImVec2(x, y));
}
draw->PathStroke(wave_color, false, 1.6f);
}
static std::vector<ImVec2> star_offsets;
static std::vector<float> star_radii;
static std::vector<float> star_rotations;
static std::vector<float> star_opacities;
constexpr float kStarRadius = 7.5f;
constexpr float kStarMinDistance = 12.0f;
if (star_offsets.empty())
{
star_offsets.reserve(16);
star_radii.reserve(16);
star_rotations.reserve(16);
star_opacities.reserve(16);
unsigned seed = 1234567u;
const char* title_text = "Mocha";
float title_reserved = 12.0f + ImGui::CalcTextSize(title_text).x + 16.0f;
float x_min = ImClamp(title_reserved, 10.0f, size.x - 10.0f);
float x_max = size.x - 10.0f;
auto nextf = [&seed]() {
seed = seed * 1664525u + 1013904223u;
return (seed >> 8) * (1.0f / 16777216.0f);
};
const int star_count = 16;
float step = (x_max - x_min) / static_cast<float>(star_count);
for (int i = 0; i < star_count; ++i)
{
float jitter = (nextf() - 0.5f) * step * 0.35f;
float x = ImClamp(x_min + (i + 0.5f) * step + jitter, x_min, x_max);
float y = 4.0f + nextf() * (title_h - 8.0f);
ImVec2 candidate(x, y);
bool too_close = false;
for (const ImVec2& p : star_offsets)
{
if (ImLengthSqr(p - candidate) < kStarMinDistance * kStarMinDistance)
{
too_close = true;
break;
}
}
if (too_close)
continue;
star_offsets.push_back(candidate);
star_radii.push_back(kStarRadius * (0.7f + nextf() * 0.6f));
star_rotations.push_back(nextf() * (2.0f * IM_PI));
star_opacities.push_back(0.55f + nextf() * 0.45f);
}
}
draw->PushClipRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + size.x, pos.y + title_h), true);
for (size_t i = 0; i < star_offsets.size(); ++i)
{
float offset = std::sinf(t * 1.5f + static_cast<float>(i) * 0.6f) * 2.2f;
ImVec2 center = pos + star_offsets[i] + ImVec2(0.0f, offset);
float fade = star_opacities[i] * (0.85f + 0.15f * (0.5f + 0.5f * std::sinf(t * 1.5f + static_cast<float>(i) * 0.6f)));
ImU32 star_color = ImGui::ColorConvertFloat4ToU32(ImVec4(1.0f, 1.0f, 1.0f, fade));
draw_star(center, star_radii[i], star_radii[i] * 0.55f, 5, star_color, star_rotations[i]);
}
draw->PopClipRect();
ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPosX() + 2.f, ImGui::GetCursorPosY() - 2.f));
ImGui::Text("Mocha");
}
@@ -213,6 +324,15 @@ int main(int, char**)
ImGui::SetCursorPos(ImVec2(((size.x - text_size.x) * 0.5f), 5.f));
ImGui::Text(text);
}
// content
{
ImGui::SetCursorPos(ImVec2(10, 40));
ImGui::Checkbox("Test Toggle", &test_bool);
ImGui::SetCursorPos(ImVec2(10, ImGui::GetCursorPosY() + 25.f));; ImGui::SliderFloat("Test Slider (float)", &test_float, 0.f, 100.f);
ImGui::SetCursorPosX(10); ImGui::SliderInt("Test Slider (int)", &test_int, 0, 100);
}
}
ImGui::EndChild();
}
+98 -26
View File
@@ -1128,7 +1128,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
const float square_sz = GetFrameHeight();
const float square_sz = GetFrameHeight() - 2.5f;
const ImVec2 pos = window->DC.CursorPos;
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
ItemSize(total_bb, style.FramePadding.y);
@@ -1146,27 +1146,34 @@ bool ImGui::Checkbox(const char* label, bool* v)
MarkItemEdited(id);
}
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
const ImRect check_bb(pos + ImVec2(0.f, 2.5f), pos + ImVec2(square_sz, square_sz) + ImVec2(0.f, 2.5f));
RenderNavHighlight(total_bb, id);
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
RenderFrame(check_bb.Min, check_bb.Max, IM_COL32(55, 60, 75, 255), true, 5.f);
ImU32 check_col = GetColorU32(ImGuiCol_CheckMark);
bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0;
if (mixed_value)
if (*v)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
ImVec2 pad(ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)), ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
const ImU32 grad_tl = IM_COL32(133, 151, 255, 255);
const ImU32 grad_tr = IM_COL32(133, 151, 255, 255);
const ImU32 grad_br = IM_COL32(113, 131, 235, 255);
const ImU32 grad_bl = IM_COL32(113, 131, 235, 255);
window->DrawList->AddRectFilledMultiColor(check_bb.Min, check_bb.Max, grad_tl, grad_tr, grad_br, grad_bl);
for (int i = 0; i < 10; ++i)
{
const float t = (float)i / 9.0f;
const float r = 1.0f + t * 8.0f;
const float falloff = (1.0f - t) * (1.0f - t); // smoother fade
const int a = (int)(85.0f * falloff);
const float rounding = 5.0f + t * 3.0f;
window->DrawList->AddRect(check_bb.Min - ImVec2(r, r), check_bb.Max + ImVec2(r, r), IM_COL32(133, 151, 255, a), rounding, ImDrawFlags_None, 1.0f);
}
else if (*v)
{
const float pad = ImMax(1.0f, IM_TRUNC(square_sz / 6.0f));
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
window->DrawList->AddRect(check_bb.Min - ImVec2(1.0f, 1.0f), check_bb.Max + ImVec2(1.0f, 1.0f), IM_COL32(133, 151, 255, 220), 5.0f, ImDrawFlags_None, 1.5f);
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(3.0f, 3.0f), IM_COL32(255, 255, 255, 255), square_sz - 6.0f);
}
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled)
LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x + 5.f, check_bb.Min.y + style.FramePadding.y);
if (label_size.x > 0.0f)
RenderText(label_pos, label);
@@ -3061,8 +3068,17 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
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));
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f) - ImVec2(0.f, 19.f));
const ImVec2 label_pos(frame_bb.Min.x, frame_bb.Min.y - label_size.y - style.ItemInnerSpacing.y);
ImVec2 total_min = frame_bb.Min;
ImVec2 total_max = frame_bb.Max;
if (label_size.x > 0.0f)
{
total_min.y = ImMin(total_min.y, label_pos.y);
total_max.x = ImMax(total_max.x, label_pos.x + label_size.x);
}
const ImRect total_bb(total_min, total_max);
const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
ItemSize(total_bb, style.FramePadding.y);
@@ -3105,7 +3121,43 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
// Draw frame
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
RenderNavHighlight(frame_bb, id);
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
RenderFrame(frame_bb.Min, frame_bb.Max, IM_COL32(55, 60, 75, 255), true, style.FrameRounding);
// dude come on
double v_cur = 0.0, v_min_d = 0.0, v_max_d = 1.0;
switch (data_type)
{
case ImGuiDataType_S8: v_cur = (double)*(const ImS8*)p_data; v_min_d = (double)*(const ImS8*)p_min; v_max_d = (double)*(const ImS8*)p_max; break;
case ImGuiDataType_U8: v_cur = (double)*(const ImU8*)p_data; v_min_d = (double)*(const ImU8*)p_min; v_max_d = (double)*(const ImU8*)p_max; break;
case ImGuiDataType_S16: v_cur = (double)*(const ImS16*)p_data; v_min_d = (double)*(const ImS16*)p_min; v_max_d = (double)*(const ImS16*)p_max; break;
case ImGuiDataType_U16: v_cur = (double)*(const ImU16*)p_data; v_min_d = (double)*(const ImU16*)p_min; v_max_d = (double)*(const ImU16*)p_max; break;
case ImGuiDataType_S32: v_cur = (double)*(const ImS32*)p_data; v_min_d = (double)*(const ImS32*)p_min; v_max_d = (double)*(const ImS32*)p_max; break;
case ImGuiDataType_U32: v_cur = (double)*(const ImU32*)p_data; v_min_d = (double)*(const ImU32*)p_min; v_max_d = (double)*(const ImU32*)p_max; break;
case ImGuiDataType_S64: v_cur = (double)*(const ImS64*)p_data; v_min_d = (double)*(const ImS64*)p_min; v_max_d = (double)*(const ImS64*)p_max; break;
case ImGuiDataType_U64: v_cur = (double)*(const ImU64*)p_data; v_min_d = (double)*(const ImU64*)p_min; v_max_d = (double)*(const ImU64*)p_max; break;
case ImGuiDataType_Float: v_cur = (double)*(const float*)p_data; v_min_d = (double)*(const float*)p_min; v_max_d = (double)*(const float*)p_max; break;
case ImGuiDataType_Double: v_cur = *(const double*)p_data; v_min_d = *(const double*)p_min; v_max_d = *(const double*)p_max; break;
default: break;
}
float t = 0.0f;
if (v_max_d != v_min_d)
{
t = ImSaturate((float)((v_cur - v_min_d) / (v_max_d - v_min_d)));
t = ImFloor(t * 25.0f + 0.5f) / 25.0f;
}
const float fill_x = ImFloor(ImLerp(frame_bb.Min.x, frame_bb.Max.x, t) * 25.0f + 0.5f) / 25.0f;
if (fill_x > frame_bb.Min.x)
{
ImDrawList* draw_list = window->DrawList;
const ImVec2 fill_max(fill_x, frame_bb.Max.y);
const int vert_start_idx = draw_list->VtxBuffer.Size;
draw_list->AddRectFilled(frame_bb.Min, fill_max, IM_COL32(255, 255, 255, 255), 25.0f);
const int vert_end_idx = draw_list->VtxBuffer.Size;
ShadeVertsLinearColorGradientKeepAlpha(draw_list, vert_start_idx, vert_end_idx, frame_bb.Min, fill_max, IM_COL32(129, 183, 255, 255), IM_COL32(137, 120, 255, 255));
}
// Slider behavior
ImRect grab_bb;
@@ -3113,19 +3165,39 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
if (value_changed)
MarkItemEdited(id);
// Render grab
if (grab_bb.Max.x > grab_bb.Min.x)
window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? 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_data, format);
DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
ImGuiStorage* storage = GetStateStorage();
const ImGuiID value_anim_id = id ^ 0x7A9C31F2;
float value_pop_t = storage->GetFloat(value_anim_id, 0.0f);
if (hovered)
value_pop_t = ImMin(value_pop_t + 6.0f * g.IO.DeltaTime, 1.0f);
else
value_pop_t = ImMax(value_pop_t - 8.0f * g.IO.DeltaTime, 0.0f);
storage->SetFloat(value_anim_id, value_pop_t);
if (value_pop_t > 0.0f)
{
const ImVec2 value_size = CalcTextSize(value_buf, NULL, true);
const float x = frame_bb.Max.x - value_size.x - style.FramePadding.x;
const float y_hidden = frame_bb.Max.y + style.FramePadding.y + value_size.y;
const float y_shown = frame_bb.Min.y - value_size.y - 3.5f;
const float pop = 1.0f - ImPow(1.0f - value_pop_t, 3.0f);
const ImVec2 value_pos(x, ImLerp(y_hidden, y_shown, pop));
// Clip so text inside the slider is masked, creating a "behind slider" effect.
window->DrawList->PushClipRect(window->ClipRect.Min, ImVec2(window->ClipRect.Max.x, frame_bb.Min.y), true);
RenderText(value_pos, value_buf);
window->DrawList->PopClipRect();
}
if (label_size.x > 0.0f)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | (temp_input_allowed ? ImGuiItemStatusFlags_Inputable : 0));
return value_changed;