#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); } static void button(gui *_g, widget *_this, int x, int y, int key_modifiers, int button, int up) { struct gui *g = _g; int d[3]; LOGD("BUTTON timeline %p xy %d %d button %d up %d\n", _this, x, y, button, up); /* scroll up */ if (button == 4 && up == 0) { d[0] = x; d[1] = y; d[2] = key_modifiers; gui_notify(g, "scrollup", _this, d); } /* scroll down */ if (button == 5 && up == 0) { d[0] = x; d[1] = y; d[2] = key_modifiers; gui_notify(g, "scrolldown", _this, d); } /* button 1/2/3 */ if ((button == 1 || button == 2 || button == 3) && up == 0) { gui_notify(g, "click", _this, &button); } } /*************************************************************************/ /* 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; w->common.button = button; gunlock(g); return w; } /*************************************************************************/ /* public functions */ /*************************************************************************/ static void _timeline_clear(gui *_gui, widget *_this, int silent) { 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; if (silent == 0) send_event(g, DIRTY, this->common.id); gunlock(g); } void timeline_clear(gui *_gui, widget *_this) { _timeline_clear(_gui, _this, 0); } void timeline_clear_silent(gui *_gui, widget *_this) { _timeline_clear(_gui, _this, 1); } static void _timeline_add_points(gui *_gui, widget *_this, int subline, int color, int *x, int len, int silent) { 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; } if (silent == 0) 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) { _timeline_add_points(_gui, _this, subline, color, x, len, 0); } void timeline_add_points_silent(gui *_gui, widget *_this, int subline, int color, int *x, int len) { _timeline_add_points(_gui, _this, subline, color, x, len, 1); } 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); } void timeline_get_width(gui *_gui, widget *_this, int *width) { struct gui *g = _gui; struct timeline_widget *this = _this; glock(g); *width = this->common.width == 0 ? this->wanted_width : this->common.width; gunlock(g); }