git.haldean.org qb / 17c4b24
lots of improvements around styling/drawing, esp for playhead haldean 5 months ago
6 changed file(s) with 132 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
5656 #=== EXECUTABLE: qb
5757 set(QB_SOURCES
5858 launch.c
59 colors.cpp
60 colors.hpp
5961 qb.cpp
6062 qb.hpp
6163 qbshim.cpp
0 #include "imgui.h"
1 #include "colors.hpp"
2
3 namespace qb {
4 namespace theme {
5 int32_t colors[color::ncolors] = {0};
6
7 static const char * colorname(color c) {
8 switch (c) {
9 case background: return "background";
10 case waveform: return "waveform";
11 case playhead: return "playhead";
12 }
13 return "unknown";
14 }
15
16 void setdefault() {
17 colors[color::background] = IM_COL32(99, 0, 29, 255);
18 colors[color::waveform] = IM_COL32(255, 158, 0, 255);
19 colors[color::playhead] = IM_COL32(154, 0, 42, 255);
20 }
21
22 void showeditor() {
23 ImGui::Begin("theme editor");
24 for (int c = 0; c < ncolors; c++) {
25 ImVec4 ic = ImColor(colors[c]);
26 ImGui::ColorEdit4(colorname((color)c), &ic.x);
27 colors[c] = ImColor(ic);
28 }
29 ImGui::ShowStyleEditor();
30 ImGui::End();
31 }
32 }
33 }
0 #include <cstdint>
1
2 namespace qb {
3 namespace theme {
4 enum color {
5 background,
6 waveform,
7 playhead,
8 ncolors
9 };
10
11 extern int32_t colors[color::ncolors];
12
13 void setdefault();
14 void showeditor();
15 }
16 }
00 #include "qb.hpp"
1 #include "colors.hpp"
12 #include "nodeui.hpp"
23
34 #include "AudioFile/AudioFile.h"
5455 const double width = corner.x - origin.x;
5556 const double scale = width / (s1 - s0);
5657
57 ImDrawList *drawlist = ImGui::GetWindowDrawList();
58 ImDrawList * const drawlist = ImGui::GetWindowDrawList();
5859 for (int64_t s = std::max(int64_t(1), s0 + 1);
5960 s <= s1 && s < (int64_t) r.size(); s++) {
6061 const ImVec2 a(origin.x + scale * (s - 1 - s0),
6162 origin.y + rad * (1.0 - r[s - 1]));
6263 const ImVec2 b(origin.x + scale * (s - s0),
6364 origin.y + rad * (1.0 - r[s]));
64 drawlist->AddLine(a, b, IM_COL32(255, 255, 0, 255));
65 drawlist->AddLine(a, b, theme::colors[theme::color::waveform]);
6566 }
6667 }
6768 }
00 #include "qb.hpp"
1 #include "colors.hpp"
12 #include "nodeui.hpp"
23 #include "task.hpp"
34 #include "AudioFile/AudioFile.h"
89 #include <cmath>
910
1011 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
1119 context::context() {
1220 _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;
1342 }
1443
1544 void context::frame(int width, int height) {
1645 taskpool::get().frame();
1746 spinstep++;
47 this->width = width;
48 this->height = height;
1849
1950 ImGui::SetNextWindowPos(ImVec2(0, 0));
2051 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;
3358 for (const auto &n : _nodes) {
3459 minframe = std::min(minframe, n->minframe());
3560 maxframe = std::max(maxframe, n->maxframe());
3661 }
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 }
3992
4093 for (const auto &n : _nodes) {
4194 draw_node(n);
4295 }
4396 ImGui::End();
97 ImGui::PopStyleColor();
98
99 qb::theme::showeditor();
44100 }
45101
46102 void context::shutdown() {
9999 void frame(int width, int height);
100100 void shutdown();
101101
102 int frame2pixel(int frame);
103 int pixel2frame(int frame);
104
102105 int playhead = 0;
103106 int visrad = 240;
107 int width = 0;
108 int height = 0;
104109
105110 // for ui animations
106111 uint32_t spinstep = 0;
107112
108113 private:
114 int mmbclicked = -1;
109115 int _framerate = 24;
110116 std::vector<qb::node_ptr> _nodes;
111117 };