|
|
@@ -43,8 +43,18 @@ static GdkColor colors[] = { |
|
|
|
{ .red = 0x8000, .green = 0x8000, .blue = 0x8000, }, |
|
|
|
}; |
|
|
|
|
|
|
|
#define MOD_CONTINUOUS 0x0001 |
|
|
|
#define MOD_SINGLESHOT 0x0002 |
|
|
|
#define MOD_RUNNING 0x0004 |
|
|
|
#define MOD_STOPPED 0x0008 |
|
|
|
|
|
|
|
static int graph_mode = MOD_CONTINUOUS | MOD_RUNNING; |
|
|
|
static struct timeval base; |
|
|
|
|
|
|
|
static GtkWidget *box; |
|
|
|
static GtkWidget *legend; |
|
|
|
static GtkWidget *yscale_min, *yscale_max; |
|
|
|
static GtkWidget *start_button, *mode_button; |
|
|
|
|
|
|
|
static GList *graphlist; |
|
|
|
|
|
|
@@ -105,9 +115,85 @@ static void update_legend(void) |
|
|
|
g_string_free(tmp, TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
static void rescale_graphs(gboolean reset) |
|
|
|
{ |
|
|
|
static GtkDataboxValue min; |
|
|
|
static GtkDataboxValue max; |
|
|
|
|
|
|
|
GtkDataboxValue tmp_min, tmp_max; |
|
|
|
|
|
|
|
if (gtk_databox_calculate_extrema(GTK_DATABOX(box), &tmp_min, &tmp_max) < 0) |
|
|
|
return; |
|
|
|
|
|
|
|
/* swap y: min/max (high values -> higher on screen) */ |
|
|
|
if (!reset) { |
|
|
|
min.x = MIN(min.x, tmp_min.x); |
|
|
|
max.x = MAX(max.x, tmp_max.x); |
|
|
|
min.y = MAX(min.y, tmp_max.y); |
|
|
|
max.y = MIN(max.y, tmp_min.y); |
|
|
|
|
|
|
|
} else { |
|
|
|
min.x = tmp_min.x; |
|
|
|
max.x = tmp_max.x; |
|
|
|
min.y = tmp_max.y; |
|
|
|
max.y = tmp_min.y; |
|
|
|
} |
|
|
|
|
|
|
|
char tmp[64]; |
|
|
|
snprintf(tmp, sizeof(tmp), "y-Min: %0.0lf", max.y); |
|
|
|
gtk_label_set_text(GTK_LABEL(yscale_min), tmp); |
|
|
|
|
|
|
|
snprintf(tmp, sizeof(tmp), "y-Max: %0.0lf", min.y); |
|
|
|
gtk_label_set_text(GTK_LABEL(yscale_max), tmp); |
|
|
|
|
|
|
|
gtk_databox_set_canvas(GTK_DATABOX(box), min, max); |
|
|
|
} |
|
|
|
|
|
|
|
static void rescale_button_cb(GtkWidget *widget, gpointer data) |
|
|
|
{ |
|
|
|
rescale_graphs(TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
static void update_button_labels(void) |
|
|
|
{ |
|
|
|
if (graph_mode & MOD_SINGLESHOT) |
|
|
|
gtk_button_set_label(GTK_BUTTON(mode_button), "Single Shot"); |
|
|
|
else if (graph_mode & MOD_CONTINUOUS) |
|
|
|
gtk_button_set_label(GTK_BUTTON(mode_button), "Continuous"); |
|
|
|
|
|
|
|
if (graph_mode & MOD_RUNNING) |
|
|
|
gtk_button_set_label(GTK_BUTTON(start_button), "Halt"); |
|
|
|
else if (graph_mode & MOD_STOPPED) |
|
|
|
gtk_button_set_label(GTK_BUTTON(start_button), "Start"); |
|
|
|
} |
|
|
|
|
|
|
|
static void mode_button_cb(GtkWidget *widget, gpointer data) |
|
|
|
{ |
|
|
|
if (graph_mode & MOD_SINGLESHOT) |
|
|
|
graph_mode = (graph_mode & ~MOD_SINGLESHOT) | MOD_CONTINUOUS; |
|
|
|
|
|
|
|
else if (graph_mode & MOD_CONTINUOUS) |
|
|
|
graph_mode = (graph_mode & ~MOD_CONTINUOUS) | MOD_SINGLESHOT; |
|
|
|
|
|
|
|
update_button_labels(); |
|
|
|
} |
|
|
|
|
|
|
|
static void start_button_cb(GtkWidget *widget, gpointer data) |
|
|
|
{ |
|
|
|
if (graph_mode & MOD_STOPPED) { |
|
|
|
graph_mode = (graph_mode & ~MOD_STOPPED) | MOD_RUNNING; |
|
|
|
gettimeofday(&base, NULL); |
|
|
|
|
|
|
|
} else if (graph_mode & MOD_RUNNING) { |
|
|
|
graph_mode = (graph_mode & ~MOD_RUNNING) | MOD_STOPPED; |
|
|
|
} |
|
|
|
|
|
|
|
update_button_labels(); |
|
|
|
} |
|
|
|
|
|
|
|
gint gui_graphtab_init(GtkNotebook *notebook) |
|
|
|
{ |
|
|
|
GtkWidget *table = gtk_table_new(5, 4, FALSE); |
|
|
|
GtkWidget *table = gtk_table_new(5, 6, FALSE); |
|
|
|
box = gtk_databox_new(); |
|
|
|
|
|
|
|
gtk_table_attach(GTK_TABLE(table), box, 1, 4, 1, 2, |
|
|
@@ -141,13 +227,27 @@ gint gui_graphtab_init(GtkNotebook *notebook) |
|
|
|
gtk_databox_graph_add(GTK_DATABOX(box), grid); |
|
|
|
|
|
|
|
legend = gtk_label_new(NULL); |
|
|
|
gtk_table_attach(GTK_TABLE(table), legend, 1, 2, 3, 4, 0, 0, 10, 10); |
|
|
|
gtk_table_attach(GTK_TABLE(table), legend, 1, 2, 3, 6, 0, 0, 5, 5); |
|
|
|
|
|
|
|
yscale_max = gtk_label_new("y-Max:"); |
|
|
|
gtk_table_attach(GTK_TABLE(table), yscale_max, 2, 3, 3, 4, 0, 0, 5, 5); |
|
|
|
|
|
|
|
yscale_min = gtk_label_new("y-Min:"); |
|
|
|
gtk_table_attach(GTK_TABLE(table), yscale_min, 2, 3, 4, 5, 0, 0, 5, 5); |
|
|
|
|
|
|
|
GtkWidget *rescale_button = gtk_button_new_with_label("Autoscale"); |
|
|
|
gtk_table_attach(GTK_TABLE(table), rescale_button, 2, 3, 5, 6, 0, 0, 10, 10); |
|
|
|
g_signal_connect(G_OBJECT(rescale_button), "clicked", G_CALLBACK(rescale_button_cb), NULL); |
|
|
|
|
|
|
|
GtkWidget *button2 = gtk_button_new_with_label("Mode"); |
|
|
|
gtk_table_attach(GTK_TABLE(table), button2, 2, 3, 3, 4, 0, 0, 10, 10); |
|
|
|
start_button = gtk_button_new_with_label("Start"); |
|
|
|
gtk_table_attach(GTK_TABLE(table), start_button, 3, 4, 4, 5, 0, 0, 10, 10); |
|
|
|
g_signal_connect(G_OBJECT(start_button), "clicked", G_CALLBACK(start_button_cb), NULL); |
|
|
|
|
|
|
|
GtkWidget *button3 = gtk_button_new_with_label("Stopp"); |
|
|
|
gtk_table_attach(GTK_TABLE(table), button3, 3, 4, 3, 4, 0, 0, 10, 10); |
|
|
|
mode_button = gtk_button_new_with_label("Continuous"); |
|
|
|
gtk_table_attach(GTK_TABLE(table), mode_button, 3, 4, 5, 6, 0, 0, 10, 10); |
|
|
|
g_signal_connect(G_OBJECT(mode_button), "clicked", G_CALLBACK(mode_button_cb), NULL); |
|
|
|
|
|
|
|
update_button_labels(); |
|
|
|
|
|
|
|
GtkWidget *label = gtk_label_new(" Graph "); |
|
|
|
return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label); |
|
|
@@ -206,42 +306,15 @@ static int calc_index(struct timeval *base, struct timeval *now, int step) |
|
|
|
return diff.tv_usec / step; |
|
|
|
} |
|
|
|
|
|
|
|
static void rescale_graphs(gboolean reset) |
|
|
|
{ |
|
|
|
static GtkDataboxValue min; |
|
|
|
static GtkDataboxValue max; |
|
|
|
|
|
|
|
GtkDataboxValue tmp_min, tmp_max; |
|
|
|
|
|
|
|
if (gtk_databox_calculate_extrema(GTK_DATABOX(box), &tmp_min, &tmp_max) < 0) |
|
|
|
return; |
|
|
|
|
|
|
|
float swap = tmp_min.y; |
|
|
|
tmp_min.y = tmp_max.y; |
|
|
|
tmp_max.y = swap; |
|
|
|
|
|
|
|
if (!reset) { |
|
|
|
min.x = MIN(min.x, tmp_min.x); |
|
|
|
min.y = MAX(min.y, tmp_min.y); |
|
|
|
max.x = MAX(max.x, tmp_max.x); |
|
|
|
max.y = MIN(max.y, tmp_max.y); |
|
|
|
|
|
|
|
} else { |
|
|
|
min.x = tmp_min.x; |
|
|
|
min.y = tmp_min.y; |
|
|
|
max.x = tmp_max.x; |
|
|
|
max.y = tmp_max.y; |
|
|
|
} |
|
|
|
|
|
|
|
gtk_databox_set_canvas(GTK_DATABOX(box), min, max); |
|
|
|
} |
|
|
|
|
|
|
|
void gui_graphtab_update_var(struct tdc_var *var) |
|
|
|
{ |
|
|
|
static struct timeval base, update; |
|
|
|
static struct timeval update; |
|
|
|
|
|
|
|
struct xygraph *graph = (struct xygraph *)var->privdata_graphtab; |
|
|
|
|
|
|
|
if (graph_mode & MOD_STOPPED) |
|
|
|
return; |
|
|
|
|
|
|
|
struct timeval now; |
|
|
|
gettimeofday(&now, NULL); |
|
|
|
|
|
|
@@ -250,6 +323,11 @@ void gui_graphtab_update_var(struct tdc_var *var) |
|
|
|
base.tv_sec = now.tv_sec; |
|
|
|
base.tv_usec = now.tv_usec; |
|
|
|
i = 0; |
|
|
|
|
|
|
|
if (graph_mode & MOD_SINGLESHOT) { |
|
|
|
graph_mode = (graph_mode & ~MOD_RUNNING) | MOD_STOPPED; |
|
|
|
update_button_labels(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
float last_value = graph->yarr[graph->last_index]; |