From 944dad4caa5a96965d99de1f442429a12bb92cbb Mon Sep 17 00:00:00 2001 From: Cedric Roux <cedric.roux@eurecom.fr> Date: Thu, 12 May 2016 17:03:07 +0200 Subject: [PATCH] GUI timeline widget --- common/utils/T/tracer/gui/Makefile | 3 +- common/utils/T/tracer/gui/gui.h | 10 ++ common/utils/T/tracer/gui/gui_defs.h | 19 +++- common/utils/T/tracer/gui/timeline.c | 150 +++++++++++++++++++++++++++ common/utils/T/tracer/gui/widget.c | 3 +- 5 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 common/utils/T/tracer/gui/timeline.c diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index b64af3bd18..7129d390b9 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -2,7 +2,8 @@ CC=gcc CFLAGS=-Wall -g -pthread OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ - gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o + gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o \ + timeline.o gui.a: $(OBJS) ar cr gui.a $(OBJS) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index ab4bf503f4..5902ea2831 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -26,6 +26,8 @@ widget *new_label(gui *gui, const char *text); widget *new_xy_plot(gui *gui, int width, int height, char *label, int vruler_width); widget *new_textlist(gui *gui, int width, int nlines, int background_color); +widget *new_timeline(gui *gui, int width, int number_of_sublines, + int subline_height); void label_set_clickable(gui *gui, widget *label, int clickable); @@ -52,6 +54,12 @@ void textlist_get_line(gui *gui, widget *this, int line, char **text, int *color); void textlist_set_color(gui *gui, widget *this, int line, int color); +void timeline_clear(gui *gui, widget *this); +void timeline_add_points(gui *gui, widget *this, int subline, int color, + int *x, int len); +void timeline_set_subline_background_color(gui *gui, widget *this, + int subline, int color); + void gui_loop(gui *gui); void glock(gui *gui); @@ -67,6 +75,8 @@ int new_color(gui *gui, char *color); * - click { int [2]: line, button } * - label: * - click { int: button } (if enabled) + * - timeline + * - resize { int: width } */ /* same type as in gui_defs.h */ diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index dd76922179..8f15747490 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -30,7 +30,8 @@ extern int volatile gui_logd; /*************************************************************************/ enum widget_type { - TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL + TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL, + TIMELINE }; struct widget_list; @@ -117,6 +118,22 @@ struct xy_plot_widget { int nplots; }; +struct timeline_subline { + int *color; /* length = width of timeline widget + * value = -1 if no color + */ + int width; + int background; /* background color of the subline */ +}; + +struct timeline_widget { + struct widget common; + int n; /* number of sublines */ + struct timeline_subline *s; + int subline_height; + int wanted_width; +}; + struct button_widget { struct widget common; }; diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c new file mode 100644 index 0000000000..9e794dda4c --- /dev/null +++ b/common/utils/T/tracer/gui/timeline.c @@ -0,0 +1,150 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include <stdio.h> +#include <stdlib.h> + +static void paint(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + int i; + int j; + + for (i = 0; i < this->n; i++) { + x_fill_rectangle(g->x, g->xwin, this->s[i].background, + this->common.x, this->common.y + i * this->subline_height, + this->common.width, this->subline_height); + for (j = 0; j < this->s[i].width; j++) + if (this->s[i].color[j] != -1) + x_draw_line(g->x, g->xwin, this->s[i].color[j], + this->common.x + j, this->common.y + i * this->subline_height, + this->common.x + j, this->common.y + this->subline_height -1 + + i * this->subline_height); + } + + LOGD("PAINT timeline xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height); +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + struct timeline_widget *w = _w; + *width = w->wanted_width; + *height = w->n * w->subline_height; + LOGD("HINTS timeline wh %d %d\n", *width, *height); +} + +static void allocate(gui *_gui, widget *_this, + int x, int y, int width, int height) +{ + struct timeline_widget *this = _this; + int i; + int j; + this->common.x = x; + this->common.y = y; + this->common.width = width; + this->common.height = height; + LOGD("ALLOCATE timeline %p xywh %d %d %d %d\n", this, x, y, width, height); + for (i = 0; i < this->n; i++) { + this->s[i].width = width; + this->s[i].color = realloc(this->s[i].color, width * sizeof(int)); + if (this->s[i].color == NULL) abort(); + for (j = 0; j < width; j++) this->s[i].color[j] = -1; + } + gui_notify(_gui, "resize", _this, &width); +} + +/*************************************************************************/ +/* creation function */ +/*************************************************************************/ + +widget *new_timeline(gui *_gui, int width, int number_of_sublines, + int subline_height) +{ + struct gui *g = _gui; + struct timeline_widget *w; + int i; + int j; + + glock(g); + + w = new_widget(g, TIMELINE, sizeof(struct timeline_widget)); + + w->wanted_width = width; + w->n = number_of_sublines; + w->s = calloc(w->n, sizeof(struct timeline_subline)); if (w->s == NULL) OOM; + w->subline_height = subline_height; + + /* initialize colors */ + for (i = 0; i < w->n; i++) { + w->s[i].width = width; + w->s[i].color = calloc(width, sizeof(int)); + if (w->s[i].color == NULL) abort(); + for (j = 0; j < width; j++) w->s[i].color[j] = -1; + w->s[i].background = BACKGROUND_COLOR; + } + + w->common.paint = paint; + w->common.hints = hints; + w->common.allocate = allocate; + + gunlock(g); + + return w; +} + +/*************************************************************************/ +/* public functions */ +/*************************************************************************/ + +void timeline_clear(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + int i; + int j; + + glock(g); + + for (i = 0; i < this->n; i++) + for (j = 0; j < this->s[i].width; j++) + this->s[i].color[j] = -1; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} + +void timeline_add_points(gui *_gui, widget *_this, int subline, int color, + int *x, int len) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + int i; + + glock(g); + + for (i = 0; i < len; i++) { + if (x[i] >= this->s[subline].width) { WARN("out of bounds\n"); continue; } + this->s[subline].color[x[i]] = color; + } + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} + +void timeline_set_subline_background_color(gui *_gui, widget *_this, + int subline, int color) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + + glock(g); + + this->s[subline].background = color; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index db8a754a70..944d27548f 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -265,7 +265,7 @@ void widget_dirty(gui *_gui, widget *_this) static const char *names[] = { "TOPLEVEL_WINDOW", "CONTAINER", "POSITIONER", "TEXT_LIST", - "XY_PLOT", "BUTTON", "LABEL" + "XY_PLOT", "BUTTON", "LABEL", "TIMELINE" }; const char *widget_name(enum widget_type type) { @@ -278,6 +278,7 @@ const char *widget_name(enum widget_type type) case XY_PLOT: case BUTTON: case LABEL: + case TIMELINE: return names[type]; } return "UNKNOWN (error)"; -- 2.26.2