diff options
Diffstat (limited to 'gtk/toneview.c')
-rw-r--r-- | gtk/toneview.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/gtk/toneview.c b/gtk/toneview.c new file mode 100644 index 0000000..79750fe --- /dev/null +++ b/gtk/toneview.c @@ -0,0 +1,107 @@ +#include <gtk/gtk.h> +#include "toneview.h" +#include <stdatomic.h> +#include <stdbool.h> + +struct toneview_g toneview_g; + +static struct { + GtkWidget *tonewin; + GtkWidget *label[6]; + struct fmplayer_tonedata tonedata; + struct fmplayer_tonedata tonedata_n; + char strbuf[FMPLAYER_TONEDATA_STR_SIZE]; + enum fmplayer_tonedata_format format; + bool normalize; + GtkClipboard *clipboard; +} g; + +static void on_destroy(GtkWidget *w, gpointer ptr) { + (void)w; + (void)ptr; + g.tonewin = 0; +} + +gboolean tick_cb(GtkWidget *widget, GdkFrameClock *clock, gpointer ptr) { + (void)widget; + (void)clock; + (void)ptr; + bool xchg = false; + if (atomic_compare_exchange_weak_explicit(&toneview_g.flag, &xchg, true, + memory_order_acquire, memory_order_relaxed)) { + g.tonedata = toneview_g.tonedata; + atomic_store_explicit(&toneview_g.flag, false, memory_order_release); + } + g.tonedata_n = g.tonedata; + for (int c = 0; c < 6; c++) { + if (g.normalize) { + tonedata_ch_normalize_tl(&g.tonedata_n.ch[c]); + } + tonedata_ch_string(g.format, g.strbuf, &g.tonedata_n.ch[c], 0); + gtk_label_set_text(GTK_LABEL(g.label[c]), g.strbuf); + } + return G_SOURCE_CONTINUE; +} + +static void on_format_changed(GtkComboBox *widget, gpointer ptr) { + (void)ptr; + g.format = gtk_combo_box_get_active(widget); +} + +static void on_normalize_toggled(GtkToggleButton *widget, gpointer ptr) { + (void)ptr; + g.normalize = gtk_toggle_button_get_active(widget); +} + +static void on_copy_clicked(GtkButton *button, gpointer ptr) { + (void)button; + int c = (intptr_t)ptr; + if (!g.clipboard) { + GdkDisplay *disp = gdk_display_get_default(); + if (disp) { + g.clipboard = gtk_clipboard_get_default(disp); + } + } + if (g.clipboard) { + tonedata_ch_string(g.format, g.strbuf, &g.tonedata_n.ch[c], 0); + gtk_clipboard_set_text(g.clipboard, g.strbuf, -1); + } +} + +void show_toneview(void) { + if (!g.tonewin) { + g.tonewin = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(g.tonewin), "FM Tone Viewer"); + g_signal_connect(g.tonewin, "destroy", G_CALLBACK(on_destroy), 0); + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); + gtk_container_add(GTK_CONTAINER(g.tonewin), box); + GtkWidget *ctrlbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + gtk_container_add(GTK_CONTAINER(box), ctrlbox); + GtkWidget *format = gtk_combo_box_text_new(); + gtk_box_pack_start(GTK_BOX(ctrlbox), format, FALSE, TRUE, 0); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(format), "PMD"); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(format), "FMP"); + gtk_combo_box_set_active(GTK_COMBO_BOX(format), g.format); + g_signal_connect(format, "changed", G_CALLBACK(on_format_changed), 0); + GtkWidget *normalizecheck = gtk_check_button_new_with_label("Normalize"); + gtk_box_pack_start(GTK_BOX(ctrlbox), normalizecheck, FALSE, TRUE, 0); + g_signal_connect(normalizecheck, "toggled", G_CALLBACK(on_normalize_toggled), 0); + for (int c = 0; c < 6; c++) { + GtkWidget *cbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + gtk_box_pack_start(GTK_BOX(box), cbox, TRUE, TRUE, 0); + GtkWidget *tonetext = gtk_label_new(0); + PangoAttrList *pattrl = pango_attr_list_new(); + PangoAttribute *pattr = pango_attr_family_new("monospace"); + pango_attr_list_insert(pattrl, pattr); + gtk_label_set_attributes(GTK_LABEL(tonetext), pattrl); + pango_attr_list_unref(pattrl); + gtk_box_pack_start(GTK_BOX(cbox), tonetext, TRUE, TRUE, 0); + GtkWidget *copybutton = gtk_button_new_with_label("Copy"); + g_signal_connect(copybutton, "clicked", G_CALLBACK(on_copy_clicked), (gpointer)((intptr_t)c)); + gtk_box_pack_start(GTK_BOX(cbox), copybutton, FALSE, TRUE, 0); + g.label[c] = tonetext; + } + gtk_widget_add_tick_callback(g.tonewin, tick_cb, 0, 0); + gtk_widget_show_all(g.tonewin); + } +} |