Mercurial > hg > xmms-sid
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... */ |