diff options
Diffstat (limited to 'src/ui.cpp')
| -rw-r--r-- | src/ui.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/ui.cpp b/src/ui.cpp new file mode 100644 index 0000000..a4b033b --- /dev/null +++ b/src/ui.cpp @@ -0,0 +1,162 @@ +#include <bits/stdc++.h> +#include "ui.hpp" + +using namespace std; + +void GTKUI::draw(cairo_t* cr, GtkWidget* drawing_area, gpointer user_data) +{ + GTKUI* gtk = (GTKUI*)user_data; + AudioData* audiodata = gtk->audiodata; + + float window_width = 900; + float window_height = 900; + float radius = 200; + float space = 50; + float delta, x, y; + + delta = 2 * M_PI / audiodata->get_channel_cnt(); + + cairo_set_source_rgba(cr, 1, 1, 1, 1); + cairo_arc(cr, window_width / 2, window_height / 2, space, 0, 2 * M_PI); + cairo_fill(cr); + + cairo_set_source_rgba(cr, 1, 0, 0, 1); + for (int i = 0; i < audiodata->get_channel_cnt(); i += 2) { + x = (radius + space) * cos(i * delta / 2); + y = (radius + space) * sin(i * delta / 2); + + cairo_arc(cr, window_width / 2 - x, window_height / 2 - y, audiodata->get_channels()[i] * radius, 0, 2 * M_PI); + cairo_arc(cr, window_width / 2 + x, window_height / 2 + y, audiodata->get_channels()[i + 1] * radius, 0, 2 * M_PI); + } + cairo_fill(cr); + + gtk_widget_queue_draw(drawing_area); +} + +void GTKUI::draw_cb(GtkDrawingArea* drawing_area, cairo_t* cr, int width, int height, gpointer user_data) +{ + GTKUI* gtk = (GTKUI*)user_data; + AudioData* audiodata = gtk->audiodata; + + if (audiodata->get_channel_cnt() == 0) + return; + + cairo_paint(cr); + draw(cr, GTK_WIDGET(drawing_area), user_data); +} + +struct ButtonData { + GTKUI* gtk; + int select_device; +}; + +void GTKUI::select_device(GtkWidget* widget, gpointer user_data) +{ + ButtonData* buttond = (ButtonData*)user_data; + GTKUI* gtk = buttond->gtk; + AudioData* audiodata = gtk->audiodata; + + audiodata->set_device_num(buttond->select_device); + audiodata->start_stream(); + + gtk_widget_add_tick_callback(gtk->drawing_area, gtk->drawCallback, user_data, NULL); +} + +void GTKUI::refresh(GtkWidget* widget, gpointer user_data) +{ + GTKUI* gtk = (GTKUI*)user_data; + AudioData* audiodata = gtk->audiodata; + + Pa_Terminate(); + Pa_Initialize(); + + int numDevices = Pa_GetDeviceCount(); + + if (numDevices < 0) { + printf("Error getting device count.\n"); + exit(EXIT_FAILURE); + } else if (numDevices == 0) { + printf("There are no available audio devices on this machine.\n"); + exit(EXIT_SUCCESS); + } + + GtkWidget* button; + + for (int i = 0; i < numDevices; i++) { + const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo(i); + + ButtonData* buttond = new ButtonData; + buttond->gtk = gtk; + buttond->select_device = i; + + button = gtk_button_new_with_label(deviceInfo->name); + gtk->buttons.push_back(button); + g_signal_connect(button, "clicked", G_CALLBACK(select_device), buttond); + gtk_grid_attach(GTK_GRID(gtk->grid), button, 0, numDevices - i - 1, 1, 1); + } + + gtk_widget_queue_draw(gtk->grid); +} + +void GTKUI::close_window(GtkWidget* widget, gpointer user_data) +{ + GTKUI* gtk = (GTKUI*)user_data; + AudioData* audiodata = gtk->audiodata; + + audiodata->close_stream(); + gtk_window_destroy(GTK_WINDOW(gtk->window)); +} + +gboolean GTKUI::drawCallback(GtkWidget* widget, GdkFrameClock* frame_clock, gpointer user_data) +{ + if (widget) { + gtk_widget_queue_draw(GTK_WIDGET(widget)); + } + return true; +} + +void GTKUI::activate(GtkApplication* app, gpointer user_data) +{ + GTKUI* gtk = (GTKUI*)user_data; + + // init window + gtk->window = gtk_application_window_new(app); + gtk_window_set_title(GTK_WINDOW(gtk->window), "Directional Audio Visualizer"); + + // init grid + gtk->grid = gtk_grid_new(); + gtk_window_set_child(GTK_WINDOW(gtk->window), gtk->grid); + + // init drawing_area + gtk->drawing_area = gtk_drawing_area_new(); + gtk_widget_set_size_request(gtk->drawing_area, 900, 900); + gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(gtk->drawing_area), draw_cb, user_data, NULL); + + gtk_grid_attach(GTK_GRID(gtk->grid), gtk->drawing_area, 1, 2, 100, 100); + + // init audio devices + Pa_Initialize(); + refresh(gtk->window, user_data); + + // init button for refresh + gtk->refresh_button = gtk_button_new_with_label("Refresh"); + g_signal_connect(gtk->refresh_button, "clicked", G_CALLBACK(gtk->refresh), gtk); + gtk_grid_attach(GTK_GRID(gtk->grid), gtk->refresh_button, 1, 0, 1, 1); + + // init button for quit + gtk->quit_button = gtk_button_new_with_label("Quit"); + g_signal_connect(gtk->quit_button, "clicked", G_CALLBACK(gtk->close_window), gtk); + gtk_grid_attach(GTK_GRID(gtk->grid), gtk->quit_button, 1, 1, 1, 1); + + // set window + gtk_window_present(GTK_WINDOW(gtk->window)); +} + +GTKUI::GTKUI(int argc, char* argv[]) +{ + this->audiodata = new AudioData; + app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect(app, "activate", G_CALLBACK(activate), this); + status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); +} |
