timeline.c 5.47 KB
Newer Older
Cedric Roux's avatar
Cedric Roux committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#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);
}

57 58
static void button(gui *_g, widget *_this, int x, int y,
    int key_modifiers, int button, int up)
Cedric Roux's avatar
Cedric Roux committed
59 60
{
  struct gui *g = _g;
61
  struct timeline_widget *w = _this;
62
  int d[3];
Cedric Roux's avatar
Cedric Roux committed
63 64 65
  LOGD("BUTTON timeline %p xy %d %d button %d up %d\n", _this, x, y, button, up);
  /* scroll up */
  if (button == 4 && up == 0) {
66 67
    d[0] = x - w->common.x;
    d[1] = y - w->common.y;
68 69
    d[2] = key_modifiers;
    gui_notify(g, "scrollup", _this, d);
Cedric Roux's avatar
Cedric Roux committed
70 71 72
  }
  /* scroll down */
  if (button == 5 && up == 0) {
73 74
    d[0] = x - w->common.x;
    d[1] = y - w->common.y;
75 76
    d[2] = key_modifiers;
    gui_notify(g, "scrolldown", _this, d);
Cedric Roux's avatar
Cedric Roux committed
77
  }
Cedric Roux's avatar
Cedric Roux committed
78 79 80 81
  /* button 1/2/3 */
  if ((button == 1 || button == 2 || button == 3) && up == 0) {
    gui_notify(g, "click", _this, &button);
  }
Cedric Roux's avatar
Cedric Roux committed
82 83
}

Cedric Roux's avatar
Cedric Roux committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/*************************************************************************/
/*                           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;
Cedric Roux's avatar
Cedric Roux committed
117
  w->common.button = button;
Cedric Roux's avatar
Cedric Roux committed
118 119 120 121 122 123 124 125 126 127

  gunlock(g);

  return w;
}

/*************************************************************************/
/*                           public functions                            */
/*************************************************************************/

128
static void _timeline_clear(gui *_gui, widget *_this, int silent)
Cedric Roux's avatar
Cedric Roux committed
129 130 131 132 133 134 135 136 137 138 139 140
{
  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;

141 142
  if (silent == 0)
    send_event(g, DIRTY, this->common.id);
Cedric Roux's avatar
Cedric Roux committed
143 144 145 146

  gunlock(g);
}

147 148 149 150 151 152 153 154 155 156 157 158
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)
Cedric Roux's avatar
Cedric Roux committed
159 160 161 162 163 164 165 166 167 168 169 170
{
  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;
  }

171 172
  if (silent == 0)
    send_event(g, DIRTY, this->common.id);
Cedric Roux's avatar
Cedric Roux committed
173 174 175 176

  gunlock(g);
}

177 178 179 180 181 182 183 184 185 186 187 188
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);
}

Cedric Roux's avatar
Cedric Roux committed
189 190 191 192 193 194 195 196 197 198 199 200 201 202
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);
}
203 204 205 206 207 208 209 210 211 212 213 214

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);
}