+ Line graph: added dot support
[calfwidgets.git] / src / linegraph.cpp
blob14f34f732c94eb5ba84d15493c6b6d5f49104d5a
1 /* Calf DSP Library
2 * Line graph custom control
3 * Copyright (C) 2007-2008 Krzysztof Foltman
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 #include <calfwidgets/linegraph.h>
21 #include <gdk/gdkkeysyms.h>
22 #include <cairo/cairo.h>
23 #include <math.h>
24 #include <stdint.h>
25 #include <malloc.h>
27 static gboolean
28 calf_line_graph_expose (GtkWidget *widget, GdkEventExpose *event)
30 g_assert(CALF_IS_LINE_GRAPH(widget));
32 CalfLineGraph *lg = CALF_LINE_GRAPH(widget);
33 int ox = widget->allocation.x + 1, oy = widget->allocation.y + 1;
34 int sx = widget->allocation.width - 2, sy = widget->allocation.height - 2;
36 cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(widget->window));
38 GdkColor sc = { 0, 0, 0, 0 };
40 gdk_cairo_set_source_color(c, &sc);
41 cairo_rectangle(c, ox, oy, sx, sy);
42 cairo_fill(c);
44 if (lg->source) {
45 float *data = new float[2 * sx];
46 GdkColor sc2 = { 0, 0, 65535, 0 };
47 gdk_cairo_set_source_color(c, &sc2);
48 cairo_set_line_join(c, CAIRO_LINE_JOIN_MITER);
49 cairo_set_line_width(c, 1);
50 for(int gn = 0; lg->source->get_graph(lg->source_id, gn, data, 2 * sx, c); gn++)
52 for (int i = 0; i < 2 * sx; i++)
54 int y = (int)(oy + sy / 2 - (sy / 2 - 1) * data[i]);
55 if (y < oy) y = oy;
56 if (y >= oy + sy) y = oy + sy - 1;
57 if (i)
58 cairo_line_to(c, ox + i * 0.5, y);
59 else
60 cairo_move_to(c, ox, y);
62 cairo_stroke(c);
64 float x, y;
65 int size = 0;
66 GdkColor sc3 = { 0, 32767, 65535, 0 };
67 gdk_cairo_set_source_color(c, &sc3);
68 for(int gn = 0; lg->source->get_dot(lg->source_id, gn, x, y, size = 3, c); gn++)
70 int yv = (int)(oy + sy / 2 - (sy / 2 - 1) * y);
71 cairo_arc(c, ox + (x + 1) * sx / 2, yv, size, 0, 2 * M_PI);
72 cairo_fill(c);
74 delete []data;
77 cairo_destroy(c);
79 gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, ox - 1, oy - 1, sx + 2, sy + 2);
80 // printf("exposed %p %d+%d\n", widget->window, widget->allocation.x, widget->allocation.y);
82 return TRUE;
85 static void
86 calf_line_graph_size_request (GtkWidget *widget,
87 GtkRequisition *requisition)
89 g_assert(CALF_IS_LINE_GRAPH(widget));
91 // CalfLineGraph *lg = CALF_LINE_GRAPH(widget);
94 static void
95 calf_line_graph_size_allocate (GtkWidget *widget,
96 GtkAllocation *allocation)
98 g_assert(CALF_IS_LINE_GRAPH(widget));
100 widget->allocation = *allocation;
101 // printf("allocation %d x %d\n", allocation->width, allocation->height);
104 static void
105 calf_line_graph_class_init (CalfLineGraphClass *klass)
107 // GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
108 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
109 widget_class->expose_event = calf_line_graph_expose;
110 widget_class->size_request = calf_line_graph_size_request;
111 widget_class->size_allocate = calf_line_graph_size_allocate;
114 static void
115 calf_line_graph_init (CalfLineGraph *self)
117 GtkWidget *widget = GTK_WIDGET(self);
118 GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
119 widget->requisition.width = 40;
120 widget->requisition.height = 40;
123 GtkWidget *
124 calf_line_graph_new()
126 return GTK_WIDGET( g_object_new (CALF_TYPE_LINE_GRAPH, NULL ));
129 GType
130 calf_line_graph_get_type (void)
132 static GType type = 0;
133 if (!type) {
134 static const GTypeInfo type_info = {
135 sizeof(CalfLineGraphClass),
136 NULL, /* base_init */
137 NULL, /* base_finalize */
138 (GClassInitFunc)calf_line_graph_class_init,
139 NULL, /* class_finalize */
140 NULL, /* class_data */
141 sizeof(CalfLineGraph),
142 0, /* n_preallocs */
143 (GInstanceInitFunc)calf_line_graph_init
146 GTypeInfo *type_info_copy = new GTypeInfo(type_info);
148 for (int i = 0; ; i++) {
149 char *name = g_strdup_printf("CalfLineGraph%u%d", ((unsigned int)(intptr_t)calf_line_graph_class_init) >> 16, i);
150 if (g_type_from_name(name)) {
151 free(name);
152 continue;
154 type = g_type_register_static( GTK_TYPE_WIDGET,
155 name,
156 type_info_copy,
157 (GTypeFlags)0);
158 free(name);
159 break;
162 return type;