From 8180ac3472ed0148befc01d5494abc9dced64b00 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Fri, 18 Apr 2008 18:14:32 +0200 Subject: [PATCH] add some graph work --- gtdc.c | 2 +- gui_graph_tab.c | 169 ++++++++++++++++++++++++++++++++++++++++++--- gui_graph_tab.h | 13 ++++ gui_variable_tab.c | 14 ++-- gui_variable_tab.h | 2 +- tdc_store.c | 9 ++- tdc_variable.h | 3 +- 7 files changed, 192 insertions(+), 20 deletions(-) create mode 100644 gui_graph_tab.h diff --git a/gtdc.c b/gtdc.c index 3b9b63a..d8f96cd 100644 --- a/gtdc.c +++ b/gtdc.c @@ -19,10 +19,10 @@ #include #include +#include "gui_graph_tab.h" #include "gui_variable_tab.h" gint gui_ctrltab_init(GtkNotebook *notebook); -gint gui_graphtab_init(GtkNotebook *notebook); int main(int argc, char *argv[]) { diff --git a/gui_graph_tab.c b/gui_graph_tab.c index e315d5e..43a2dc8 100644 --- a/gui_graph_tab.c +++ b/gui_graph_tab.c @@ -16,29 +16,116 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include +#include + +#include + #include #include +#include + +#include "tdc_variable.h" +#include "gui_graph_tab.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define HISTORY 1000 + +static unsigned int used_colors; +static GdkColor colors[] = { + { .red = 0x0000, .green = 0x0000, .blue = 0xFF00, }, + { .red = 0xFF00, .green = 0x0000, .blue = 0x0000, }, + { .red = 0x0000, .green = 0xDF00, .blue = 0x0000, }, + { .red = 0x0000, .green = 0xFF00, .blue = 0xFF00, }, + { .red = 0xFF00, .green = 0x0000, .blue = 0xFF00, }, + { .red = 0xA500, .green = 0x2A00, .blue = 0x2A00, }, + { .red = 0xFF00, .green = 0xA500, .blue = 0x0000, }, + { .red = 0x8000, .green = 0x8000, .blue = 0x8000, }, +}; + +static GtkWidget *box; +static GtkWidget *legend; + +static GList *graphlist; + +struct xygraph { + GtkDataboxGraph *graph; + struct tdc_var *var; + + gfloat xarr[HISTORY]; + gfloat yarr[HISTORY]; + GdkColor *color; + + struct timeval base; +}; + +static GdkColor * get_color(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(colors); i++) { + if (used_colors & (1 << i)) + continue; + + used_colors |= (1 << i); + return colors +i; + } + return NULL; +} + +static void free_color(GdkColor *color) +{ + int i; + for (i = 0; i < ARRAY_SIZE(colors); i++) + if (color == colors +i) + used_colors &= ~(1 << i); +} + +static void update_legend_cb(gpointer data, gpointer user_data) +{ + struct xygraph *graph = (struct xygraph *)data; + GString *tmp = (GString *)user_data; + + g_string_append_printf(tmp,"%s\n", + (graph->color->red >> 8) & 0xFF, + (graph->color->green >> 8) & 0xFF, + (graph->color->blue >> 8) & 0xFF, + graph->var->name); +} + +static void update_legend(void) +{ + GString *tmp; + tmp = g_string_new(""); + g_list_foreach(graphlist, &update_legend_cb, tmp); + + tmp->str[tmp->len -1] = 0x00; + + gtk_label_set_markup(GTK_LABEL(legend), tmp->str); + g_string_free(tmp, TRUE); +} gint gui_graphtab_init(GtkNotebook *notebook) { - GtkWidget *table = gtk_table_new(3, 3, FALSE); - GtkWidget *box = gtk_databox_new(); - gtk_table_attach(GTK_TABLE(table), box, 1, 2, 1, 2, + GtkWidget *table = gtk_table_new(5, 4, FALSE); + box = gtk_databox_new(); + + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 1, 2, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0); GtkWidget *scrollbar = gtk_hscrollbar_new(gtk_databox_get_hadjustment(GTK_DATABOX(box))); - gtk_table_attach(GTK_TABLE(table), scrollbar, 1, 2, 2, 3, + gtk_table_attach(GTK_TABLE(table), scrollbar, 1, 4, 2, 3, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL, 0, 0); scrollbar = gtk_vscrollbar_new(gtk_databox_get_vadjustment(GTK_DATABOX(box))); - gtk_table_attach(GTK_TABLE(table), scrollbar, 2, 3, 1, 2, + gtk_table_attach(GTK_TABLE(table), scrollbar, 4, 5, 1, 2, GTK_FILL, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0); GtkWidget *ruler = gtk_hruler_new(); - gtk_table_attach(GTK_TABLE(table), ruler, 1, 2, 0, 1, + gtk_table_attach(GTK_TABLE(table), ruler, 1, 4, 0, 1, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL, 0, 0); gtk_databox_set_hruler(GTK_DATABOX(box), GTK_RULER(ruler)); @@ -49,12 +136,72 @@ gint gui_graphtab_init(GtkNotebook *notebook) GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0); gtk_databox_set_vruler(GTK_DATABOX(box), GTK_RULER(ruler)); - /* - * TODO: - * komplette datenhaltung.. (wie skalieren?) - * legende der graphen - */ + legend = gtk_label_new(NULL); + gtk_table_attach(GTK_TABLE(table), legend, 1, 2, 3, 4, 0, 0, 10, 10); + + GtkWidget *button2 = gtk_button_new_with_label("Mode"); + gtk_table_attach(GTK_TABLE(table), button2, 2, 3, 3, 4, 0, 0, 10, 10); + + GtkWidget *button3 = gtk_button_new_with_label("Stopp"); + gtk_table_attach(GTK_TABLE(table), button3, 3, 4, 3, 4, 0, 0, 10, 10); + + struct tdc_var *var = tdcvar_create(1, 0, "test", 4); + gui_graphtab_add_var(var); + gui_graphtab_add_var(var); + gui_graphtab_add_var(var); + gui_graphtab_add_var(var); + gui_graphtab_add_var(var); + gui_graphtab_add_var(var); + gui_graphtab_add_var(var); + gui_graphtab_add_var(var); GtkWidget *label = gtk_label_new(" Graph "); return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label); } + +int gui_graphtab_add_var(struct tdc_var *var) +{ + GdkColor *color = get_color(); + if (color == NULL) + return -1; + + struct xygraph *graph = g_malloc0(sizeof(struct xygraph)); + graph->graph = gtk_databox_lines_new(HISTORY, graph->xarr, graph->yarr, color, 1); + graph->var = var; + graph->color = color; + + var->privdata_graphtab = graph; + + int i; + for (i = 0; i < HISTORY; i++) { + graph->xarr[i] = i - HISTORY; + graph->yarr[i] = sin(((int)graph % 127) + i * 4 * M_PI / 1024); + } + + graphlist = g_list_append(graphlist, graph); + + gtk_databox_graph_add(GTK_DATABOX(box), graph->graph); + gtk_databox_auto_rescale(GTK_DATABOX(box), 0.05); + update_legend(); + + return 0; +} + +void gui_graphtab_remove_var(struct tdc_var *var) +{ + struct xygraph *graph = (struct xygraph *)var->privdata_graphtab; + + gtk_databox_graph_remove(GTK_DATABOX(box), graph->graph); + g_free(graph->graph); + free_color(graph->color); + + graphlist = g_list_remove(graphlist, graph); + graph->var->privdata_graphtab = NULL; + g_free(graph); +} + +void gui_graphtab_update_var(struct tdc_var *var) +{ + struct xygraph *graph = (struct xygraph *)var->privdata_graphtab; + // do some updates, i think +} diff --git a/gui_graph_tab.h b/gui_graph_tab.h new file mode 100644 index 0000000..0c786d3 --- /dev/null +++ b/gui_graph_tab.h @@ -0,0 +1,13 @@ +#ifndef GRAPH_TAB_H_ +#define GRAPH_TAB_H_ + +#include +#include "tdc_variable.h" + +gint gui_graphtab_init(GtkNotebook *notebook); + +int gui_graphtab_add_var(struct tdc_var *var); +void gui_graphtab_update_var(struct tdc_var *var); +void gui_graphtab_remove_var(struct tdc_var *var); + +#endif /* GRAPH_TAB_H_ */ diff --git a/gui_variable_tab.c b/gui_variable_tab.c index 3c761db..27c0db7 100644 --- a/gui_variable_tab.c +++ b/gui_variable_tab.c @@ -246,23 +246,27 @@ void gui_vartab_add_var(struct tdc_var *var) COL_NAME, var->name, -1); - var->privdata = gtk_tree_iter_copy(&it); + var->privdata_vartab = gtk_tree_iter_copy(&it); } -void gui_vartab_update_var(struct tdc_var *var) +int gui_vartab_update_var(struct tdc_var *var) { // TODO: update even in graph mode every xxx ms if (var == current_edited_var || (var->flags & TDC_GUI_GRAPH)) - return; + return 0; /* do a dummy write to update cells */ - GtkTreeIter *it = (GtkTreeIter *)var->privdata; + GtkTreeIter *it = (GtkTreeIter *)var->privdata_vartab; gtk_list_store_set(list_store, it, -1); + + return 0; } void gui_vartab_remove_var(struct tdc_var *var) { - GtkTreeIter *it = (GtkTreeIter *)var->privdata; + GtkTreeIter *it = (GtkTreeIter *)var->privdata_vartab; gtk_list_store_remove(list_store, it); gtk_tree_iter_free(it); + + var->privdata_vartab = NULL; } diff --git a/gui_variable_tab.h b/gui_variable_tab.h index eb45c74..b4eaaf7 100644 --- a/gui_variable_tab.h +++ b/gui_variable_tab.h @@ -6,7 +6,7 @@ gint gui_vartab_init(GtkNotebook *notebook); -void gui_vartab_add_var(struct tdc_var *var); +int gui_vartab_add_var(struct tdc_var *var); void gui_vartab_update_var(struct tdc_var *var); void gui_vartab_remove_var(struct tdc_var *var); diff --git a/tdc_store.c b/tdc_store.c index a8eb26a..960fe7c 100644 --- a/tdc_store.c +++ b/tdc_store.c @@ -26,6 +26,7 @@ #include "tdc_store.h" #include "tdc_variable.h" +#include "gui_graph_tab.h" #include "gui_variable_tab.h" struct tdc_board { @@ -117,7 +118,13 @@ int tdcstore_update_var(int address, int id, uint8_t *data, int len) return -1; tdcvar_update(var, data, len); - gui_vartab_update_var(var); + + if (var->privdata_vartab) + gui_vartab_update_var(var); + + if (var->privdata_graphtab) + gui_graphtab_update_var(var); + return 0; } diff --git a/tdc_variable.h b/tdc_variable.h index 8649fc7..e739b5d 100644 --- a/tdc_variable.h +++ b/tdc_variable.h @@ -16,7 +16,8 @@ struct tdc_var { double data_double; }; - void *privdata; + void *privdata_vartab; /* GtkTreeIter */ + void *privdata_graphtab; /* struct xygraph */ char name[0]; };