comparison src/xs_curve.c @ 602:b6c7c26569cc

Updates from curve branch.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 30 Aug 2007 15:08:00 +0000
parents b37c7f430c3f
children ce1fe59627f2
comparison
equal deleted inserted replaced
601:45ac346884d6 602:b6c7c26569cc
1 /* 1 /*
2 XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS) 2 XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
3 3
4 XSCurve, a custom Gtk+ spline widget for representing SIDPlay2/reSID 4 XSCurve, a custom Gtk+ spline widget for representing SIDPlay2/reSID
5 filter curves in the configuration GUI. Implementation based heavily 5 filter curves in the configuration GUI. Implementation based heavily
6 on GtkCurve from Gtk+ 1.2.10 (C) 1997 David Mosberger. 6 on GtkCurve from Gtk+ 1.2.10 (C) 1997 David Mosberger & Gtk-team.
7 Spline formula from reSID 0.16 (C) 2004 Dag Lem. 7 Spline formula from reSID 0.16 (C) 2004 Dag Lem.
8 8
9 Programmed by Matti 'ccr' Hamalainen <ccr@tnsp.org> 9 Programmed by Matti 'ccr' Hamalainen <ccr@tnsp.org>
10 (C) Copyright 2006-2007 Tecnic Software productions (TNSP) 10 (C) Copyright 2006-2007 Tecnic Software productions (TNSP)
11 11
113 static void xs_curve_init(XSCurve *curve) 113 static void xs_curve_init(XSCurve *curve)
114 { 114 {
115 gint old_mask; 115 gint old_mask;
116 116
117 curve->pixmap = NULL; 117 curve->pixmap = NULL;
118 curve->height = 0;
119 curve->grab_point = -1; 118 curve->grab_point = -1;
120 119
121 curve->nctlpoints = 0; 120 curve->nctlpoints = 0;
122 curve->ctlpoints = NULL; 121 curve->ctlpoints = NULL;
123 122
205 } 204 }
206 205
207 206
208 static void xs_curve_draw(XSCurve *curve, gint width, gint height) 207 static void xs_curve_draw(XSCurve *curve, gint width, gint height)
209 { 208 {
210 gfloat res = 10.0f; 209 gfloat res = 5.0f;
211 GtkStateType state; 210 GtkStateType state;
212 GtkStyle *style; 211 GtkStyle *style;
213 gint i; 212 gint i, ox = -1, oy = -1;
214 t_xs_point *p0, *p1, *p2, *p3; 213 t_xs_point *p0, *p1, *p2, *p3;
215 214
216 if (!curve->pixmap) 215 if (!curve->pixmap)
217 return; 216 return;
218 217
240 gdk_draw_line(curve->pixmap, style->dark_gc[state], 239 gdk_draw_line(curve->pixmap, style->dark_gc[state],
241 i * (width / 4.0) + RADIUS, RADIUS, 240 i * (width / 4.0) + RADIUS, RADIUS,
242 i * (width / 4.0) + RADIUS, height + RADIUS); 241 i * (width / 4.0) + RADIUS, height + RADIUS);
243 } 242 }
244 243
245 #define Qprintf(x,y,...)
246
247 #if 1 244 #if 1
248 /* Draw the spline/curve itself */ 245 /* Draw the spline/curve itself */
249 p0 = curve->ctlpoints; 246 p0 = curve->ctlpoints;
250 p1 = p0; 247 p1 = p0;
251 p2 = p1; p2++; 248 p2 = p1; p2++;
252 p3 = p2; p3++; 249 p3 = p2; p3++;
253 250
254 /* Draw each curve segment */ 251 /* Draw each curve segment */
255 Qprintf(stderr, "-- npoints = %d\n", curve->nctlpoints);
256 if (curve->nctlpoints > 5) 252 if (curve->nctlpoints > 5)
257 for (i = 0; i < curve->nctlpoints; i++, ++p0, ++p1, ++p2, ++p3) { 253 for (i = 0; i < curve->nctlpoints; i++, ++p0, ++p1, ++p2, ++p3) {
254 gint n;
258 gfloat k1, k2, a, b, c, d, x; 255 gfloat k1, k2, a, b, c, d, x;
259 256
260 Qprintf(stderr, "#%d: ", i);
261 if (p1->x == p2->x) 257 if (p1->x == p2->x)
262 continue; 258 continue;
263 #define PPASK(q, p) Qprintf(stderr, q "=[%1.3f, %1.3f] ", p->x, p->y) 259
264
265 PPASK("p0", p1);
266 PPASK("p1", p1);
267 PPASK("p2", p2);
268 PPASK("p3", p3);
269
270 Qprintf(stderr, "\ncase #");
271 if (p0->x == p1->x && p2->x == p3->x) { 260 if (p0->x == p1->x && p2->x == p3->x) {
272 Qprintf(stderr, "1");
273 k1 = k2 = (p2->y - p1->y) / (p2->x - p1->x); 261 k1 = k2 = (p2->y - p1->y) / (p2->x - p1->x);
274 } else if (p0->x == p1->x) { 262 } else if (p0->x == p1->x) {
275 Qprintf(stderr, "2");
276 k2 = (p3->y - p1->y) / (p3->x - p1->x); 263 k2 = (p3->y - p1->y) / (p3->x - p1->x);
277 k1 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k2) / 2; 264 k1 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k2) / 2;
278 } else if (p2->x == p3->x) { 265 } else if (p2->x == p3->x) {
279 Qprintf(stderr, "3");
280 k1 = (p2->y - p0->y) / (p2->x - p0->x); 266 k1 = (p2->y - p0->y) / (p2->x - p0->x);
281 k2 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k1) / 2; 267 k2 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k1) / 2;
282 } else { 268 } else {
283 Qprintf(stderr, "4");
284 k1 = (p2->y - p0->y) / (p2->x - p0->x); 269 k1 = (p2->y - p0->y) / (p2->x - p0->x);
285 k2 = (p3->y - p1->y) / (p3->x - p1->x); 270 k2 = (p3->y - p1->y) / (p3->x - p1->x);
286 } 271 }
287 272
288 xs_cubic_coeff(p1->x, p1->y, p2->x, p2->y, k1, k2, &a, &b, &c, &d); 273 xs_cubic_coeff(p1->x, p1->y, p2->x, p2->y, k1, k2, &a, &b, &c, &d);
289 274
290 Qprintf(stderr, " seg[%1.3f, %1.3f] => [%1.3f, %1.3f] k1=%1.3f, k2=%1.3f\n\n", 275 for (x = p1->x; x <= p2->x; x += res, n++) {
291 p1->x, p1->y,
292 p2->x, p2->y,
293 k1, k2);
294
295 for (x = p1->x; x <= p2->x; x += res) {
296 gfloat y = ((a * x + b) * x + c) * x + d; 276 gfloat y = ((a * x + b) * x + c) * x + d;
297 gint qx, qy; 277 gint qx, qy;
298 qx = RADIUS + xs_project(x, curve->min_x, curve->max_x, width); 278 qx = RADIUS + xs_project(x, curve->min_x, curve->max_x, width);
299 qy = RADIUS + xs_project(y, curve->min_y, curve->max_y, height); 279 qy = RADIUS + xs_project(y, curve->min_y, curve->max_y, height);
300 280
301 gdk_draw_point(curve->pixmap, style->fg_gc[state], 281 if (ox != -1) {
302 RADIUS + xs_project(x, curve->min_x, curve->max_x, width), 282 gdk_draw_line(curve->pixmap, style->fg_gc[state],
303 RADIUS + xs_project(y, curve->min_y, curve->max_y, height)); 283 ox, oy, qx, qy);
304 284 }
305 } 285 ox = qx; oy = qy;
306 } 286 }
307 287 }
308 Qprintf(stderr, "-------\n"); 288
309 #endif 289 #endif
310 290
311 /* Draw control points */ 291 /* Draw control points */
312 for (i = 0; i < curve->nctlpoints; ++i) { 292 for (i = 0; i < curve->nctlpoints; ++i) {
313 gint x, y; 293 gint x, y;
294 GtkStateType cstate;
314 295
315 if (GET_X(i) < curve->min_x || GET_Y(i) < curve->min_y || 296 if (GET_X(i) < curve->min_x || GET_Y(i) < curve->min_y ||
316 GET_X(i) >= curve->max_x || GET_Y(i) >= curve->max_y) 297 GET_X(i) >= curve->max_x || GET_Y(i) >= curve->max_y)
317 continue; 298 continue;
318 299
319 x = xs_project(GET_X(i), curve->min_x, curve->max_x, width); 300 x = xs_project(GET_X(i), curve->min_x, curve->max_x, width);
320 y = xs_project(GET_Y(i), curve->min_y, curve->max_y, height); 301 y = xs_project(GET_Y(i), curve->min_y, curve->max_y, height);
321 302
322 gdk_draw_arc(curve->pixmap, style->fg_gc[state], TRUE, 303 if (i == curve->grab_point) {
304 cstate = GTK_STATE_SELECTED;
305 gdk_draw_line(curve->pixmap, style->fg_gc[cstate],
306 x + RADIUS, RADIUS, x + RADIUS, height + RADIUS);
307 gdk_draw_line(curve->pixmap, style->fg_gc[cstate],
308 RADIUS, y + RADIUS, width + RADIUS, y + RADIUS);
309 } else
310 cstate = state;
311
312 gdk_draw_arc(curve->pixmap, style->fg_gc[cstate], TRUE,
323 x, y, RADIUS2, RADIUS2, 0, 360 * 64); 313 x, y, RADIUS2, RADIUS2, 0, 360 * 64);
324 } 314 }
325 315
326 /* Draw pixmap in the widget */ 316 /* Draw pixmap in the widget */
327 gdk_draw_pixmap(GTK_WIDGET(curve)->window, 317 gdk_draw_pixmap(GTK_WIDGET(curve)->window,
440 } 430 }
441 431
442 new_type = GDK_FLEUR; 432 new_type = GDK_FLEUR;
443 curve->grab_point = -1; 433 curve->grab_point = -1;
444 } 434 }
435 xs_curve_draw(curve, width, height);
445 break; 436 break;
446 437
447 case GDK_MOTION_NOTIFY: 438 case GDK_MOTION_NOTIFY:
448 if (curve->grab_point == -1) { 439 if (curve->grab_point == -1) {
449 /* if no point is grabbed... */ 440 /* if no point is grabbed... */