GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 48, 0 excluded
0.0%
Functions:
0 of 5, 0 excluded
0.0%
Branches:
0 of 68, 0 excluded
0.0%

libs/imgui/src/eu/imgui/scurve.cc
Line Branch Exec Source
1 #include "eu/imgui/scurve.h"
2
3 #include "eu/assert/assert.h"
4 #include "eu/base/cint.h"
5
6 #include "eu/imgui/ui.h"
7
8 #include "dear_imgui/imgui.h"
9
10 #include <cmath>
11
12 #include "eu/core/scurve.h"
13
14 namespace eu::imgui
15 {
16
17 SCurveGuiState::SCurveGuiState(float x, float y)
18 : drag(x, y)
19 {
20 }
21
22 SCurveGuiState SCurveGuiState::light_curve()
23 {
24 return {0.2f, 0.0f};
25 }
26
27 bool imgui_s_curve_editor(const char* title, core::SCurve* curve, SCurveGuiState* gui, FlipX flip_x, const SCurveImguiSettings& settings, bool force_init_curve)
28 {
29 imgui_text(fmt::format("{} ({} {})", title, curve->slope, curve->threshold));
30 if (ImGui::BeginChild(title, settings.widget_size, settings.widget_border ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove)
31 == false)
32 {
33 ImGui::EndChild();
34 return false;
35 }
36
37 auto& points = gui->point_cache;
38
39 bool changed = false;
40
41 const auto widget_position = ImGui::GetWindowPos();
42 const auto widget_size = ImGui::GetWindowSize();
43
44 auto* draw = ImGui::GetWindowDrawList();
45 draw->AddRectFilled(widget_position, widget_position + widget_size, settings.background_color);
46
47
48 if (points.max_size() != settings.num_points)
49 {
50 points.resize(settings.num_points);
51 }
52 for (std::size_t point_index = 0; point_index < settings.num_points; point_index += 1)
53 {
54 const float srcx = static_cast<float>(point_index) / static_cast<float>(settings.num_points - 1); // -1 here to include 1.0f when evaluating the curve
55 const float x = flip_x == FlipX::yes? 1 - srcx : srcx;
56 const float y = core::calculate_s_curve(srcx, curve->slope, curve->threshold);
57 points[point_index] = ImVec2{x * widget_size.x, (1 - y) * widget_size.y} + widget_position;
58 }
59 draw->AddPolyline(points.data(), int_from_sizet(settings.num_points), settings.line_color, ImDrawFlags_None, 1.0f);
60
61 if (settings.draw_points)
62 {
63 for (std::size_t point_index = 0; point_index < settings.num_points; point_index += 1)
64 {
65 draw->AddCircleFilled(points[point_index], settings.point_radius, settings.point_color);
66 }
67 }
68 draw->AddCircleFilled(ImVec2{gui->drag.x * widget_size.x, (1 - gui->drag.y) * widget_size.y} + widget_position, settings.drag_radius, settings.drag_color);
69
70 const auto t01 = [&widget_position, &widget_size](const ImVec2& mp)
71 {
72 const auto x = (mp.x - widget_position.x) / widget_size.x;
73 const auto y = 1 - ((mp.y - widget_position.y) / widget_size.y);
74 return ImVec2{x, y};
75 };
76
77 const auto within01 = [](const ImVec2& p)
78 {
79 #define T(s) \
80 do \
81 { \
82 if ((s) < 0.0f || (s) > 1.0f) \
83 return false; \
84 } while (false)
85 T(p.x);
86 T(p.y);
87 return true;
88 #undef T
89 };
90
91 if (ImGui::IsMouseDown(settings.button) && within01(t01(ImGui::GetIO().MouseClickedPos[settings.button])))
92 {
93 // mouse is down and drag started inside the component
94 const auto mp = ImGui::GetMousePos();
95 const auto n = t01(mp);
96 gui->drag.x = std::min(1.0f, std::max(n.x, 0.0f));
97 gui->drag.y = std::min(1.0f, std::max(n.y, 0.0f));
98 changed = true;
99 }
100
101 if (changed || force_init_curve)
102 {
103 *curve = core::s_curve_from_input(flip_x == FlipX::yes ? 1 - gui->drag.x : gui->drag.x, gui->drag.y);
104 }
105
106 ImGui::EndChild();
107
108 return changed;
109 }
110
111 } // namespace eu::imgui_extra
112