0 | 0 |
#include "qb.hpp"
|
|
1 |
#include "colors.hpp"
|
1 | 2 |
#include "nodeui.hpp"
|
2 | 3 |
#include "task.hpp"
|
3 | 4 |
#include "AudioFile/AudioFile.h"
|
|
8 | 9 |
#include <cmath>
|
9 | 10 |
|
10 | 11 |
namespace qb {
|
|
12 |
template <typename T> static T
|
|
13 |
clamp(const T &a, const T &min, const T &max) {
|
|
14 |
if (a < min) return min;
|
|
15 |
if (a > max) return max;
|
|
16 |
return a;
|
|
17 |
}
|
|
18 |
|
11 | 19 |
context::context() {
|
12 | 20 |
_nodes.push_back(std::make_shared<qb::audio_node>(this, "test/coc-mono.wav"));
|
|
21 |
qb::theme::setdefault();
|
|
22 |
}
|
|
23 |
|
|
24 |
int context::frame2pixel(int frame) {
|
|
25 |
const double off = frame - playhead;
|
|
26 |
const double ndc = off / (double)visrad;
|
|
27 |
const int px = round(width * (ndc + 1) / 2.0);
|
|
28 |
if (px < 0 || px >= width) {
|
|
29 |
return -1;
|
|
30 |
}
|
|
31 |
return px;
|
|
32 |
}
|
|
33 |
|
|
34 |
int context::pixel2frame(int frame) {
|
|
35 |
const double off = frame - playhead;
|
|
36 |
const double ndc = off / (double)visrad;
|
|
37 |
const int px = round(width * (ndc + 1) / 2.0);
|
|
38 |
if (px < 0 || px >= width) {
|
|
39 |
return -1;
|
|
40 |
}
|
|
41 |
return px;
|
13 | 42 |
}
|
14 | 43 |
|
15 | 44 |
void context::frame(int width, int height) {
|
16 | 45 |
taskpool::get().frame();
|
17 | 46 |
spinstep++;
|
|
47 |
this->width = width;
|
|
48 |
this->height = height;
|
18 | 49 |
|
19 | 50 |
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
20 | 51 |
ImGui::SetNextWindowSize(ImVec2((float) width, (float) height));
|
21 | |
ImGui::Begin("MainWindow", nullptr, ImGuiWindowFlags_NoDecoration);
|
22 | |
|
23 | |
if (ImGui::IsKeyPressed(SAPP_KEYCODE_L)) {
|
24 | |
int delta = (int) ceil(visrad * 0.02);
|
25 | |
playhead += delta;
|
26 | |
} else if (ImGui::IsKeyPressed(SAPP_KEYCODE_H)) {
|
27 | |
int delta = (int) ceil(visrad * 0.02);
|
28 | |
playhead -= delta;
|
29 | |
}
|
30 | |
|
31 | |
/*
|
32 | |
int minframe = 0, maxframe = 0;
|
|
52 |
ImGui::PushStyleColor(ImGuiCol_WindowBg, qb::theme::colors[qb::theme::background]);
|
|
53 |
ImGui::Begin("MainWindow", nullptr,
|
|
54 |
ImGuiWindowFlags_NoDecoration);
|
|
55 |
|
|
56 |
int minframe = 0;
|
|
57 |
int maxframe = 0;
|
33 | 58 |
for (const auto &n : _nodes) {
|
34 | 59 |
minframe = std::min(minframe, n->minframe());
|
35 | 60 |
maxframe = std::max(maxframe, n->maxframe());
|
36 | 61 |
}
|
37 | |
ImGui::DragIntRange2("visible", &vismin, &vismax, 1.0, minframe, maxframe);
|
38 | |
*/
|
|
62 |
|
|
63 |
if (ImGui::IsMouseDragging(ImGuiMouseButton_Middle)) {
|
|
64 |
const ImVec2 delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Middle);
|
|
65 |
const bool horiz = abs(delta.x) > abs(delta.y);
|
|
66 |
const double pxperframe = width / (2.0 * std::max(visrad, 1));
|
|
67 |
const double framedist = horiz ? ceil(0.1 * delta.x / pxperframe) : 0;
|
|
68 |
const double zoomdist = !horiz ? ceil(0.1 * delta.y / pxperframe) : 0;
|
|
69 |
playhead = clamp((int) round((double)playhead + framedist), minframe, maxframe);
|
|
70 |
visrad = clamp((int) round((double)visrad + zoomdist), 3, maxframe - minframe);
|
|
71 |
}
|
|
72 |
|
|
73 |
// draw playhead
|
|
74 |
{
|
|
75 |
ImDrawList * const drawlist = ImGui::GetWindowDrawList();
|
|
76 |
const int f0x = frame2pixel(playhead);
|
|
77 |
const int f1x = frame2pixel(playhead + 1);
|
|
78 |
if (f1x > 0 && f1x != f0x) {
|
|
79 |
ImVec2 pts[5] = {
|
|
80 |
ImVec2(f1x, 0),
|
|
81 |
ImVec2(f0x, 0),
|
|
82 |
ImVec2(f0x, height),
|
|
83 |
ImVec2(f1x, height),
|
|
84 |
ImVec2(f1x, 0)
|
|
85 |
};
|
|
86 |
drawlist->AddRectFilled(ImVec2(f0x, 0), ImVec2(f1x, height),
|
|
87 |
qb::theme::colors[qb::theme::color::playhead], 0, 1.0);
|
|
88 |
} else {
|
|
89 |
drawlist->AddLine(ImVec2(f0x, 0), ImVec2(f0x, height), qb::theme::colors[qb::theme::color::playhead]);
|
|
90 |
}
|
|
91 |
}
|
39 | 92 |
|
40 | 93 |
for (const auto &n : _nodes) {
|
41 | 94 |
draw_node(n);
|
42 | 95 |
}
|
43 | 96 |
ImGui::End();
|
|
97 |
ImGui::PopStyleColor();
|
|
98 |
|
|
99 |
qb::theme::showeditor();
|
44 | 100 |
}
|
45 | 101 |
|
46 | 102 |
void context::shutdown() {
|