everything's different
Haldean Brown
1 year, 1 month ago
0 | ((c++-mode | |
1 | . ((compile-command . "cmake --build build") | |
2 | )) | |
3 | ) | |
0 | ;;; Directory Local Variables | |
1 | ;;; For more information see (info "(emacs) Directory Variables") | |
2 | ||
3 | ((c++-mode . ((c-basic-offset . 2) | |
4 | (compile-command . "cmake --build build")))) |
47 | 47 | else() |
48 | 48 | add_library(sokol STATIC sokol/sokol.c ${SOKOL_HEADERS}) |
49 | 49 | if (CMAKE_SYSTEM_NAME STREQUAL Linux) |
50 | target_link_libraries(sokol INTERFACE X11 Xi Xcursor GL dl m) | |
50 | target_link_libraries(sokol INTERFACE X11 Xi Xcursor GL dl m asound) | |
51 | 51 | target_link_libraries(sokol PUBLIC Threads::Threads) |
52 | 52 | endif() |
53 | 53 | endif() |
69 | 69 | colors.hpp |
70 | 70 | cue.cpp |
71 | 71 | cue.hpp |
72 | fonts.cpp | |
73 | fonts.hpp | |
74 | nodeui.cpp | |
75 | nodeui.hpp | |
72 | 76 | qb.cpp |
73 | 77 | qb.hpp |
74 | 78 | qbshim.cpp |
75 | 79 | qbshim.hpp |
76 | nodeui.cpp | |
77 | nodeui.hpp | |
78 | 80 | task.cpp |
79 | 81 | task.hpp |
82 | ui.cpp | |
83 | ui.hpp | |
80 | 84 | AudioFile/AudioFile.h |
81 | 85 | ) |
82 | 86 | if (MSVC) |
Binary diff not shown
10 | 10 | case waveform: return "waveform"; |
11 | 11 | case playhead: return "playhead"; |
12 | 12 | case hit: return "track hit"; |
13 | case ruler: return "time ruler"; | |
14 | case ruler_text: return "time ruler text"; | |
13 | 15 | } |
14 | 16 | return "unknown"; |
15 | 17 | } |
16 | 18 | |
17 | 19 | void setdefault() { |
18 | colors[color::background] = IM_COL32(99, 0, 29, 255); | |
19 | colors[color::waveform] = IM_COL32(255, 158, 0, 255); | |
20 | colors[color::playhead] = IM_COL32(154, 0, 42, 255); | |
21 | colors[color::hit] = IM_COL32(0, 255, 255, 255); | |
20 | colors[color::background] = IM_COL32(5, 2, 3, 255); | |
21 | colors[color::waveform] = IM_COL32(255, 45, 0, 255); | |
22 | colors[color::playhead] = IM_COL32(255, 0, 128, 125); | |
23 | colors[color::hit] = IM_COL32(255, 203, 0, 255); | |
24 | colors[color::ruler] = IM_COL32(214, 14, 96, 255); | |
25 | colors[color::ruler_text] = IM_COL32(255, 255, 255, 255); | |
26 | ||
27 | ImVec4* colors = ImGui::GetStyle().Colors; | |
28 | colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); | |
29 | colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); | |
30 | colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); | |
31 | colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); | |
32 | colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); | |
33 | colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); | |
34 | colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); | |
35 | colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.16f, 0.16f, 0.54f); | |
36 | colors[ImGuiCol_FrameBgHovered] = ImVec4(0.30f, 0.30f, 0.30f, 0.40f); | |
37 | colors[ImGuiCol_FrameBgActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
38 | colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); | |
39 | colors[ImGuiCol_TitleBgActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
40 | colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); | |
41 | colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); | |
42 | colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); | |
43 | colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); | |
44 | colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); | |
45 | colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); | |
46 | colors[ImGuiCol_CheckMark] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
47 | colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
48 | colors[ImGuiCol_SliderGrabActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
49 | colors[ImGuiCol_Button] = ImVec4(0.52f, 0.52f, 0.52f, 0.40f); | |
50 | colors[ImGuiCol_ButtonHovered] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f); | |
51 | colors[ImGuiCol_ButtonActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
52 | colors[ImGuiCol_Header] = ImVec4(0.62f, 0.62f, 0.62f, 0.31f); | |
53 | colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 0.80f); | |
54 | colors[ImGuiCol_HeaderActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
55 | colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.43f, 0.43f, 0.50f); | |
56 | colors[ImGuiCol_SeparatorHovered] = ImVec4(0.75f, 0.00f, 0.10f, 0.78f); | |
57 | colors[ImGuiCol_SeparatorActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
58 | colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.24f); | |
59 | colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.67f); | |
60 | colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
61 | colors[ImGuiCol_Tab] = ImVec4(1.00f, 0.00f, 0.16f, 0.44f); | |
62 | colors[ImGuiCol_TabHovered] = ImVec4(1.00f, 0.00f, 0.16f, 0.80f); | |
63 | colors[ImGuiCol_TabActive] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
64 | colors[ImGuiCol_TabUnfocused] = ImVec4(0.17f, 0.10f, 0.15f, 0.97f); | |
65 | colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.47f, 0.18f, 0.28f, 1.00f); | |
66 | colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); | |
67 | colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); | |
68 | colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); | |
69 | colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); | |
70 | colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); | |
71 | colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f); | |
72 | colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f); | |
73 | colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); | |
74 | colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); | |
75 | colors[ImGuiCol_TextSelectedBg] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
76 | colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); | |
77 | colors[ImGuiCol_NavHighlight] = ImVec4(1.00f, 0.00f, 0.16f, 1.00f); | |
78 | colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); | |
79 | colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); | |
80 | colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); | |
22 | 81 | } |
23 | 82 | |
24 | 83 | void showeditor() { |
Binary diff not shown
0 | #include "cimgui/imgui/imgui.h" | |
1 | #include "sokol/sokol_gfx.h" | |
2 | ||
3 | namespace qb { | |
4 | void initfonts() { | |
5 | ImGui::GetIO().Fonts->AddFontFromFileTTF("data/InputMono-Regular.ttf", 14); | |
6 | ||
7 | unsigned char* font_pixels; | |
8 | int font_width, font_height; | |
9 | ImGui::GetIO().Fonts->GetTexDataAsRGBA32( | |
10 | &font_pixels, &font_width, &font_height); | |
11 | ||
12 | sg_image_desc img_desc; | |
13 | memset(&img_desc, 0, sizeof(img_desc)); | |
14 | img_desc.width = font_width; | |
15 | img_desc.height = font_height; | |
16 | img_desc.pixel_format = SG_PIXELFORMAT_RGBA8; | |
17 | img_desc.wrap_u = SG_WRAP_CLAMP_TO_EDGE; | |
18 | img_desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE; | |
19 | img_desc.min_filter = SG_FILTER_LINEAR; | |
20 | img_desc.mag_filter = SG_FILTER_LINEAR; | |
21 | img_desc.data.subimage[0][0].ptr = font_pixels; | |
22 | img_desc.data.subimage[0][0].size = | |
23 | (size_t)(font_width * font_height) * sizeof(uint32_t); | |
24 | img_desc.label = "input-serif-12"; | |
25 | sg_image img = sg_make_image(&img_desc); | |
26 | ImGui::GetIO().Fonts->TexID = (ImTextureID)(uintptr_t) img.id; | |
27 | } | |
28 | } |
23 | 23 | stm_setup(); |
24 | 24 | simgui_setup(&(simgui_desc_t){ |
25 | 25 | .max_vertices = 524288, |
26 | .no_default_font = true, | |
26 | 27 | }); |
27 | 28 | |
28 | 29 | // initial clear color |
29 | 30 | state.pass_action = (sg_pass_action) { |
30 | .colors[0] = { .action = SG_ACTION_CLEAR, .value = { 0.04f, 0.02f, 0.045f, 1.0 } } | |
31 | .colors[0] = { .action = SG_ACTION_CLEAR, .value = { 0.0f, 0.0f, 0.0f, 1.0 } } | |
31 | 32 | }; |
32 | 33 | state.context = qb_init(); |
33 | 34 | } |
106 | 106 | std::lower_bound(track.hits.begin(), |
107 | 107 | track.hits.end(), |
108 | 108 | (int) ctx->playhead()); |
109 | if (iter != track.hits.end() && iter != track.hits.begin()) { | |
109 | if (iter != track.hits.begin() && !track.hits.empty()) { | |
110 | 110 | hitdist = (float) (ctx->playhead() - *std::prev(iter)); |
111 | 111 | } |
112 | 112 | } |
2 | 2 | #include "audionode.hpp" |
3 | 3 | #include "colors.hpp" |
4 | 4 | #include "cue.hpp" |
5 | #include "fonts.hpp" | |
5 | 6 | #include "nodeui.hpp" |
6 | 7 | #include "task.hpp" |
8 | #include "ui.hpp" | |
7 | 9 | |
8 | 10 | #include "sokol/sokol_app.h" |
9 | 11 | #include "sokol/sokol_audio.h" |
20 | 22 | } |
21 | 23 | |
22 | 24 | context::context() { |
25 | qb::initfonts(); | |
26 | ||
23 | 27 | _nodes.push_back(std::make_shared<qb::audio_node>(this, "test/coc-mono.wav")); |
24 | 28 | |
25 | 29 | auto cuenode = std::make_shared<qb::cue_node>(this, "test/cues.txt"); |
41 | 45 | ImGui::GetIO().KeyRepeatRate = 1.0f / _framerate; |
42 | 46 | } |
43 | 47 | |
44 | int context::frame2pixel(double frame) { | |
48 | int context::frame2pixel(double frame) const { | |
45 | 49 | const double off = frame - _playhead; |
46 | 50 | const double ndc = off / (double)_visrad; |
47 | 51 | const int px = (int) round(_width * (ndc + 1) / 2.0); |
59 | 63 | |
60 | 64 | ImGui::SetNextWindowPos(ImVec2(0, 0)); |
61 | 65 | ImGui::SetNextWindowSize(ImVec2((float) _width, (float) _height)); |
62 | ImGui::PushStyleColor(ImGuiCol_WindowBg, qb::theme::colors[qb::theme::background]); | |
66 | ImGui::PushStyleColor( | |
67 | ImGuiCol_WindowBg, | |
68 | qb::theme::colors[qb::theme::background]); | |
63 | 69 | ImGui::Begin("MainWindow", nullptr, |
64 | 70 | ImGuiWindowFlags_NoDecoration); |
71 | ||
72 | qb::draw_ruler(*this); | |
73 | qb::draw_playhead(*this); | |
65 | 74 | |
66 | 75 | double minframe = 0; |
67 | 76 | double maxframe = 0; |
103 | 112 | _playhead = clamp((double)_playhead + framedist, minframe, maxframe); |
104 | 113 | _visrad = clamp((double)_visrad + zoomdist, 3.0, maxframe - minframe); |
105 | 114 | } |
106 | if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { | |
107 | const ImVec2 delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Left); | |
108 | ||
109 | } | |
110 | ||
111 | // draw _playhead | |
112 | { | |
113 | ImDrawList * const drawlist = ImGui::GetWindowDrawList(); | |
114 | const float f0x = (float) frame2pixel(_playhead); | |
115 | const float f1x = (float) frame2pixel(_playhead + 1); | |
116 | if (f1x > 0 && f1x != f0x) { | |
117 | drawlist->AddRectFilled(ImVec2(f0x, 0.0), ImVec2(f1x, (float) _height), | |
118 | qb::theme::colors[qb::theme::color::playhead]); | |
119 | } else { | |
120 | drawlist->AddLine(ImVec2(f0x, 0), ImVec2(f0x, (float) _height), | |
121 | qb::theme::colors[qb::theme::color::playhead]); | |
122 | } | |
123 | } | |
124 | 115 | |
125 | 116 | for (const auto &n : _nodes) { |
126 | 117 | draw_node(n); |
127 | 118 | } |
119 | ||
128 | 120 | ImGui::End(); |
129 | 121 | ImGui::PopStyleColor(); |
130 | 122 |
60 | 60 | context &operator=(const context &) = delete; |
61 | 61 | context &operator=(context &&) = delete; |
62 | 62 | |
63 | // get/set the playback framerate (not the UI frame rate!) | |
63 | 64 | int framerate() const { return _framerate; } |
64 | 65 | void framerate(int fr) { _framerate = fr; } |
65 | 66 | |
67 | // visible radius around playhead | |
66 | 68 | double visrad() const { return _visrad; } |
69 | // location of the playhead (in playback frames) | |
67 | 70 | double playhead() const { return _playhead; } |
71 | ||
72 | // for ui animations, incremented (with wraparound) on every UI frame. | |
68 | 73 | uint32_t spinstep() const { return _spinstep; } |
74 | ||
75 | // width and height of the qb window | |
69 | 76 | int width() const { return _width; } |
70 | 77 | int height() const { return _height; } |
71 | 78 | |
79 | // draws a frame at the given width and height | |
72 | 80 | void frame(int width, int height); |
81 | ||
82 | // kills the event loop | |
73 | 83 | void shutdown(); |
74 | 84 | |
75 | int frame2pixel(double frame); | |
85 | // translates a playback frame to a UI x-coordinate | |
86 | int frame2pixel(double frame) const; | |
76 | 87 | |
77 | 88 | private: |
78 | 89 | void initaudio(); |
85 | 96 | int _width = 0; |
86 | 97 | int _height = 0; |
87 | 98 | |
88 | // for ui animations | |
89 | 99 | uint32_t _spinstep = 0; |
90 | 100 | |
91 | 101 | bool _audioinit = false; |
1 | 1 | #define SOKOL_IMPL |
2 | 2 | #define SOKOL_IMGUI_IMPL |
3 | 3 | #define SOKOL_AUDIO_IMPL |
4 | #define SOKOL_LOG | |
4 | 5 | #if defined(_WIN32) |
5 | 6 | #define SOKOL_D3D11 |
6 | 7 | #elif defined(__EMSCRIPTEN__) |
6 | 6 | { |
7 | 7 | |
8 | 8 | using task = std::function<void(void)>; |
9 | ||
9 | 10 | struct taskpool { |
10 | 11 | static taskpool& get(); |
12 | ||
13 | // submit a task that is executed once on a separate thread | |
11 | 14 | void submit_async(const task &t); |
15 | ||
16 | // submit a task that is executed at the end of the current frame, in the | |
17 | // main thread. | |
12 | 18 | void submit_frame(const task &t); |
19 | ||
20 | // execute all frame tasks (only should be called from the main thread) | |
13 | 21 | void frame(); |
14 | 22 | |
15 | 23 | private: |
0 | #include "ui.hpp" | |
1 | ||
2 | #include "colors.hpp" | |
3 | ||
4 | #include "cimgui/imgui/imgui.h" | |
5 | ||
6 | namespace qb { | |
7 | void draw_playhead(const qb::context &ctx) | |
8 | { | |
9 | ImDrawList * const drawlist = ImGui::GetWindowDrawList(); | |
10 | const float f0x = (float) ctx.frame2pixel(ctx.playhead()); | |
11 | const float f1x = (float) ctx.frame2pixel(ctx.playhead() + 1); | |
12 | if (f1x > 0 && f1x != f0x) { | |
13 | drawlist->AddRectFilled( | |
14 | ImVec2(f0x, 0.0), ImVec2(f1x, (float) ctx.height()), | |
15 | qb::theme::colors[qb::theme::color::playhead]); | |
16 | } else { | |
17 | drawlist->AddLine( | |
18 | ImVec2(f0x, 0), ImVec2(f0x, (float) ctx.height()), | |
19 | qb::theme::colors[qb::theme::color::playhead]); | |
20 | } | |
21 | } | |
22 | ||
23 | static constexpr float ruler_height = 16; | |
24 | ||
25 | void draw_ruler(const qb::context &ctx) | |
26 | { | |
27 | ImDrawList * const drawlist = ImGui::GetWindowDrawList(); | |
28 | const float playheadx = (float) ctx.frame2pixel(ctx.playhead() + 1); | |
29 | /* | |
30 | drawlist->AddRectFilled( | |
31 | ImVec2(0, 0), ImVec2(ctx.width(), ruler_height), | |
32 | qb::theme::colors[qb::theme::color::ruler]); | |
33 | */ | |
34 | ||
35 | char buf[32] = {}; | |
36 | snprintf(buf, 32, "%.0f", ctx.playhead()); | |
37 | drawlist->AddText( | |
38 | ImGui::GetIO().Fonts->Fonts[0], | |
39 | ruler_height, | |
40 | ImVec2(playheadx, 30), | |
41 | qb::theme::color::ruler, | |
42 | "hello!"); | |
43 | } | |
44 | } |