Mercurial > hg > xmms-sid
comparison src/xs_curve.c @ 545:425da926d310
Working on XSCurve widget implementation.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 23 Feb 2007 05:10:00 +0000 |
parents | 81481e59e195 |
children | b37c7f430c3f |
comparison
equal
deleted
inserted
replaced
544:260c286108e6 | 545:425da926d310 |
---|---|
1 /* | |
2 * | |
3 * | |
4 * | |
5 */ | |
1 #include <stdlib.h> | 6 #include <stdlib.h> |
2 #include <string.h> | 7 #include <string.h> |
3 #include <math.h> | 8 #include <math.h> |
4 | |
5 #include <stdio.h> | 9 #include <stdio.h> |
6 | |
7 #include "xs_curve.h" | 10 #include "xs_curve.h" |
8 #include <gtk/gtkdrawingarea.h> | 11 #include <gtk/gtkdrawingarea.h> |
9 #include <gtk/gtkmain.h> | 12 #include <gtk/gtkmain.h> |
10 #include <gtk/gtksignal.h> | 13 #include <gtk/gtksignal.h> |
11 | 14 |
12 | 15 |
13 #define RADIUS 3 /* radius of the control points */ | 16 #define RADIUS 3 /* radius of the control points */ |
14 #define RADIUS2 (RADIUS * 2) | 17 #define RADIUS2 (RADIUS * 2) |
15 | 18 #define MIN_DISTANCE 7 /* min distance between control points */ |
16 #define MIN_DISTANCE 8 /* min distance between control points */ | 19 |
17 | 20 |
18 #define GRAPH_MASK (GDK_EXPOSURE_MASK | \ | 21 #define GRAPH_MASK (GDK_EXPOSURE_MASK | \ |
19 GDK_POINTER_MOTION_MASK | \ | 22 GDK_POINTER_MOTION_MASK | \ |
20 GDK_POINTER_MOTION_HINT_MASK | \ | 23 GDK_POINTER_MOTION_HINT_MASK | \ |
21 GDK_ENTER_NOTIFY_MASK | \ | 24 GDK_ENTER_NOTIFY_MASK | \ |
27 #define GET_Y(i) curve->ctlpoints[i].y | 30 #define GET_Y(i) curve->ctlpoints[i].y |
28 | 31 |
29 | 32 |
30 enum { | 33 enum { |
31 ARG_0, | 34 ARG_0, |
32 ARG_CURVE_TYPE, | |
33 ARG_MIN_X, | 35 ARG_MIN_X, |
34 ARG_MAX_X, | 36 ARG_MAX_X, |
35 ARG_MIN_Y, | 37 ARG_MIN_Y, |
36 ARG_MAX_Y | 38 ARG_MAX_Y |
37 }; | 39 }; |
94 | 96 |
95 curve->pixmap = NULL; | 97 curve->pixmap = NULL; |
96 curve->height = 0; | 98 curve->height = 0; |
97 curve->grab_point = -1; | 99 curve->grab_point = -1; |
98 | 100 |
99 curve->num_ctlpoints = 0; | 101 curve->nctlpoints = 0; |
100 curve->ctlpoints = NULL; | 102 curve->ctlpoints = NULL; |
101 | 103 |
102 curve->min_x = 0.0; | 104 curve->min_x = 0.0; |
103 curve->max_x = 2048.0; | 105 curve->max_x = 2047.0; |
104 curve->min_y = 0.0; | 106 curve->min_y = 0.0; |
105 curve->max_y = 22000.0; | 107 curve->max_y = 24000.0; |
106 | 108 |
107 old_mask = gtk_widget_get_events(GTK_WIDGET(curve)); | 109 old_mask = gtk_widget_get_events(GTK_WIDGET(curve)); |
108 gtk_widget_set_events(GTK_WIDGET(curve), old_mask | GRAPH_MASK); | 110 gtk_widget_set_events(GTK_WIDGET(curve), old_mask | GRAPH_MASK); |
109 gtk_signal_connect(GTK_OBJECT(curve), "event", (GtkSignalFunc) xs_curve_graph_events, curve); | 111 gtk_signal_connect(GTK_OBJECT(curve), "event", (GtkSignalFunc) xs_curve_graph_events, curve); |
110 xs_curve_size_graph(curve); | 112 xs_curve_size_graph(curve); |
218 gdk_draw_line(curve->pixmap, style->dark_gc[state], | 220 gdk_draw_line(curve->pixmap, style->dark_gc[state], |
219 i * (width / 4.0) + RADIUS, RADIUS, | 221 i * (width / 4.0) + RADIUS, RADIUS, |
220 i * (width / 4.0) + RADIUS, height + RADIUS); | 222 i * (width / 4.0) + RADIUS, height + RADIUS); |
221 } | 223 } |
222 | 224 |
225 #define Qprintf(x,y,...) | |
223 | 226 |
224 #if 1 | 227 #if 1 |
225 /* Draw the spline/curve itself */ | 228 /* Draw the spline/curve itself */ |
226 p0 = curve->ctlpoints; | 229 p0 = curve->ctlpoints; |
227 p1 = p0; | 230 p1 = p0; |
228 p2 = p1; p2++; | 231 p2 = p1; p2++; |
229 p3 = p2; p3++; | 232 p3 = p2; p3++; |
230 | 233 |
231 /* Draw each curve segment */ | 234 /* Draw each curve segment */ |
232 fprintf(stderr, "-- npoints = %d\n", curve->num_ctlpoints); | 235 Qprintf(stderr, "-- npoints = %d\n", curve->nctlpoints); |
233 if (curve->num_ctlpoints > 5) | 236 if (curve->nctlpoints > 5) |
234 for (i = 0; i < curve->num_ctlpoints; i++, ++p0, ++p1, ++p2, ++p3) { | 237 for (i = 0; i < curve->nctlpoints; i++, ++p0, ++p1, ++p2, ++p3) { |
235 gfloat k1, k2, a, b, c, d, x; | 238 gfloat k1, k2, a, b, c, d, x; |
236 fprintf(stderr, "#%d: ", i); | 239 |
240 Qprintf(stderr, "#%d: ", i); | |
237 if (p1->x == p2->x) | 241 if (p1->x == p2->x) |
238 continue; | 242 continue; |
239 #define PPASK(q, p) fprintf(stderr, q "=[%1.3f, %1.3f] ", p->x, p->y) | 243 #define PPASK(q, p) Qprintf(stderr, q "=[%1.3f, %1.3f] ", p->x, p->y) |
240 | 244 |
241 PPASK("p0", p1); | 245 PPASK("p0", p1); |
242 PPASK("p1", p1); | 246 PPASK("p1", p1); |
243 PPASK("p2", p2); | 247 PPASK("p2", p2); |
244 PPASK("p3", p3); | 248 PPASK("p3", p3); |
245 | 249 |
246 fprintf(stderr, "\ncase #"); | 250 Qprintf(stderr, "\ncase #"); |
247 if (p0->x == p1->x && p2->x == p3->x) { | 251 if (p0->x == p1->x && p2->x == p3->x) { |
248 fprintf(stderr, "1"); | 252 Qprintf(stderr, "1"); |
249 k1 = k2 = (p2->y - p1->y) / (p2->x - p1->x); | 253 k1 = k2 = (p2->y - p1->y) / (p2->x - p1->x); |
250 } else if (p0->x == p1->x) { | 254 } else if (p0->x == p1->x) { |
251 fprintf(stderr, "2"); | 255 Qprintf(stderr, "2"); |
252 k2 = (p3->y - p1->y) / (p3->x - p1->x); | 256 k2 = (p3->y - p1->y) / (p3->x - p1->x); |
253 k1 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k2) / 2; | 257 k1 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k2) / 2; |
254 } else if (p2->x == p3->x) { | 258 } else if (p2->x == p3->x) { |
255 fprintf(stderr, "3"); | 259 Qprintf(stderr, "3"); |
256 k1 = (p2->y - p0->y) / (p2->x - p0->x); | 260 k1 = (p2->y - p0->y) / (p2->x - p0->x); |
257 k2 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k1) / 2; | 261 k2 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k1) / 2; |
258 } else { | 262 } else { |
259 fprintf(stderr, "4"); | 263 Qprintf(stderr, "4"); |
260 k1 = (p2->y - p0->y) / (p2->x - p0->x); | 264 k1 = (p2->y - p0->y) / (p2->x - p0->x); |
261 k2 = (p3->y - p1->y) / (p3->x - p1->x); | 265 k2 = (p3->y - p1->y) / (p3->x - p1->x); |
262 } | 266 } |
263 | 267 |
264 xs_cubic_coeff(p1->x, p1->y, p2->x, p2->y, k1, k2, &a, &b, &c, &d); | 268 xs_cubic_coeff(p1->x, p1->y, p2->x, p2->y, k1, k2, &a, &b, &c, &d); |
265 fprintf(stderr, " seg[%1.3f, %1.3f] => [%1.3f, %1.3f] k1=%1.3f, k2=%1.3f\n\n", | 269 |
270 Qprintf(stderr, " seg[%1.3f, %1.3f] => [%1.3f, %1.3f] k1=%1.3f, k2=%1.3f\n\n", | |
266 p1->x, p1->y, | 271 p1->x, p1->y, |
267 p2->x, p2->y, | 272 p2->x, p2->y, |
268 k1, k2); | 273 k1, k2); |
269 #if 1 | 274 |
270 for (x = p1->x; x <= p2->x; x += res) { | 275 for (x = p1->x; x <= p2->x; x += res) { |
271 gfloat y = ((a * x + b) * x + c) * x + d; | 276 gfloat y = ((a * x + b) * x + c) * x + d; |
272 gint qx, qy; | 277 gint qx, qy; |
273 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); |
274 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); |
276 gdk_draw_point(curve->pixmap, style->fg_gc[state], | 281 gdk_draw_point(curve->pixmap, style->fg_gc[state], |
277 RADIUS + xs_project(x, curve->min_x, curve->max_x, width), | 282 RADIUS + xs_project(x, curve->min_x, curve->max_x, width), |
278 RADIUS + xs_project(y, curve->min_y, curve->max_y, height)); | 283 RADIUS + xs_project(y, curve->min_y, curve->max_y, height)); |
279 | 284 |
280 } | 285 } |
286 } | |
287 | |
288 Qprintf(stderr, "-------\n"); | |
281 #endif | 289 #endif |
282 } | |
283 fprintf(stderr, "-------\n"); | |
284 #endif | |
285 | 290 |
286 /* Draw control points */ | 291 /* Draw control points */ |
287 for (i = 0; i < curve->num_ctlpoints; ++i) { | 292 for (i = 0; i < curve->nctlpoints; ++i) { |
288 gint x, y; | 293 gint x, y; |
289 | 294 |
290 if (GET_X(i) < curve->min_x || GET_Y(i) < curve->min_y || | 295 if (GET_X(i) < curve->min_x || GET_Y(i) < curve->min_y || |
291 GET_X(i) >= curve->max_x || GET_Y(i) >= curve->max_y) | 296 GET_X(i) >= curve->max_x || GET_Y(i) >= curve->max_y) |
292 continue; | 297 continue; |
309 | 314 |
310 static gint xs_curve_graph_events(GtkWidget *widget, GdkEvent *event, XSCurve *curve) | 315 static gint xs_curve_graph_events(GtkWidget *widget, GdkEvent *event, XSCurve *curve) |
311 { | 316 { |
312 GdkCursorType new_type = curve->cursor_type; | 317 GdkCursorType new_type = curve->cursor_type; |
313 GdkEventButton *bevent; | 318 GdkEventButton *bevent; |
314 GdkEventMotion *mevent; | |
315 GtkWidget *w; | 319 GtkWidget *w; |
316 gint i, width, height, x, y, tx, ty, cx, closest_point = 0, min_x; | 320 gint i, width, height, x, y, tx, ty, cx, closest_point = 0, min_x; |
317 guint distance; | 321 guint distance; |
318 | 322 |
319 w = GTK_WIDGET(curve); | 323 w = GTK_WIDGET(curve); |
325 | 329 |
326 /* get the pointer position */ | 330 /* get the pointer position */ |
327 gdk_window_get_pointer(w->window, &tx, &ty, NULL); | 331 gdk_window_get_pointer(w->window, &tx, &ty, NULL); |
328 x = CLAMP((tx - RADIUS), 0, width - 1); | 332 x = CLAMP((tx - RADIUS), 0, width - 1); |
329 y = CLAMP((ty - RADIUS), 0, height - 1); | 333 y = CLAMP((ty - RADIUS), 0, height - 1); |
330 | |
331 min_x = curve->min_x; | 334 min_x = curve->min_x; |
332 | 335 |
333 distance = ~0U; | 336 distance = ~0U; |
334 for (i = 0; i < curve->num_ctlpoints; ++i) { | 337 for (i = 0; i < curve->nctlpoints; ++i) { |
335 cx = xs_project(GET_X(i), min_x, curve->max_x, width); | 338 cx = xs_project(GET_X(i), min_x, curve->max_x, width); |
336 if ((guint) abs(x - cx) < distance) { | 339 if ((guint) abs(x - cx) < distance) { |
337 distance = abs(x - cx); | 340 distance = abs(x - cx); |
338 closest_point = i; | 341 closest_point = i; |
339 } | 342 } |
362 bevent = (GdkEventButton *) event; | 365 bevent = (GdkEventButton *) event; |
363 new_type = GDK_TCROSS; | 366 new_type = GDK_TCROSS; |
364 | 367 |
365 if (distance > MIN_DISTANCE) { | 368 if (distance > MIN_DISTANCE) { |
366 /* insert a new control point */ | 369 /* insert a new control point */ |
367 if (curve->num_ctlpoints > 0) { | 370 if (curve->nctlpoints > 0) { |
368 cx = xs_project(GET_X(closest_point), min_x, curve->max_x, width); | 371 cx = xs_project(GET_X(closest_point), min_x, curve->max_x, width); |
369 if (x > cx) closest_point++; | 372 if (x > cx) closest_point++; |
370 } | 373 } |
371 | 374 |
372 curve->num_ctlpoints++; | 375 curve->nctlpoints++; |
373 | 376 |
374 curve->ctlpoints = g_realloc(curve->ctlpoints, curve->num_ctlpoints * sizeof(*curve->ctlpoints)); | 377 curve->ctlpoints = g_realloc(curve->ctlpoints, |
375 for (i = curve->num_ctlpoints - 1; i > closest_point; --i) { | 378 curve->nctlpoints * sizeof(*curve->ctlpoints)); |
376 memcpy(curve->ctlpoints + i, curve->ctlpoints + i - 1, sizeof(*curve->ctlpoints)); | 379 |
380 for (i = curve->nctlpoints - 1; i > closest_point; --i) { | |
381 memcpy(curve->ctlpoints + i, | |
382 curve->ctlpoints + i - 1, | |
383 sizeof(*curve->ctlpoints)); | |
377 } | 384 } |
378 } | 385 } |
379 | 386 |
380 curve->grab_point = closest_point; | 387 curve->grab_point = closest_point; |
381 GET_X(curve->grab_point) = xs_unproject(x, min_x, curve->max_x, width); | 388 GET_X(curve->grab_point) = xs_unproject(x, min_x, curve->max_x, width); |
389 gint src, dst; | 396 gint src, dst; |
390 | 397 |
391 gtk_grab_remove(widget); | 398 gtk_grab_remove(widget); |
392 | 399 |
393 /* delete inactive points: */ | 400 /* delete inactive points: */ |
394 for (src = dst = 0; src < curve->num_ctlpoints; ++src) | 401 for (src = dst = 0; src < curve->nctlpoints; ++src) { |
395 if (GET_X(src) >= min_x) { | 402 if (GET_X(src) >= min_x) { |
396 memcpy(curve->ctlpoints + dst, curve->ctlpoints + src, sizeof(*curve->ctlpoints)); | 403 memcpy(curve->ctlpoints + dst, |
397 dst++; | 404 curve->ctlpoints + src, |
405 sizeof(*curve->ctlpoints)); | |
406 dst++; | |
407 } | |
398 } | 408 } |
399 | 409 |
400 if (dst < src) { | 410 if (dst < src) { |
401 curve->num_ctlpoints -= (src - dst); | 411 curve->nctlpoints -= (src - dst); |
402 if (curve->num_ctlpoints <= 0) { | 412 if (curve->nctlpoints <= 0) { |
403 curve->num_ctlpoints = 1; | 413 curve->nctlpoints = 1; |
404 GET_X(0) = min_x; | 414 GET_X(0) = min_x; |
405 GET_Y(0) = curve->min_y; | 415 GET_Y(0) = curve->min_y; |
406 xs_curve_draw(curve, width, height); | 416 xs_curve_draw(curve, width, height); |
407 } | 417 } |
408 curve->ctlpoints = g_realloc(curve->ctlpoints, curve->num_ctlpoints * sizeof(*curve->ctlpoints)); | 418 curve->ctlpoints = g_realloc(curve->ctlpoints, |
419 curve->nctlpoints * sizeof(*curve->ctlpoints)); | |
409 } | 420 } |
410 | 421 |
411 new_type = GDK_FLEUR; | 422 new_type = GDK_FLEUR; |
412 curve->grab_point = -1; | 423 curve->grab_point = -1; |
413 } | 424 } |
414 break; | 425 break; |
415 | 426 |
416 case GDK_MOTION_NOTIFY: | 427 case GDK_MOTION_NOTIFY: |
417 mevent = (GdkEventMotion *) event; | |
418 | |
419 if (curve->grab_point == -1) { | 428 if (curve->grab_point == -1) { |
420 /* if no point is grabbed... */ | 429 /* if no point is grabbed... */ |
421 if (distance <= MIN_DISTANCE) | 430 if (distance <= MIN_DISTANCE) |
422 new_type = GDK_FLEUR; | 431 new_type = GDK_FLEUR; |
423 else | 432 else |
434 GET_X(curve->grab_point-1), | 443 GET_X(curve->grab_point-1), |
435 min_x, curve->max_x, width); | 444 min_x, curve->max_x, width); |
436 } | 445 } |
437 | 446 |
438 rightbound = width + RADIUS2 + MIN_DISTANCE; | 447 rightbound = width + RADIUS2 + MIN_DISTANCE; |
439 if (curve->grab_point + 1 < curve->num_ctlpoints) { | 448 if (curve->grab_point + 1 < curve->nctlpoints) { |
440 rightbound = xs_project( | 449 rightbound = xs_project( |
441 GET_X(curve->grab_point+1), | 450 GET_X(curve->grab_point+1), |
442 min_x, curve->max_x, width); | 451 min_x, curve->max_x, width); |
443 } | 452 } |
444 | 453 |
452 xs_unproject(y, curve->min_y, curve->max_y, height); | 461 xs_unproject(y, curve->min_y, curve->max_y, height); |
453 } | 462 } |
454 | 463 |
455 xs_curve_draw(curve, width, height); | 464 xs_curve_draw(curve, width, height); |
456 } | 465 } |
457 | 466 |
467 /* See if cursor type was changed and update accordingly */ | |
458 if (new_type != (GdkCursorType) curve->cursor_type) { | 468 if (new_type != (GdkCursorType) curve->cursor_type) { |
459 GdkCursor *cursor; | 469 GdkCursor *cursor; |
460 | |
461 curve->cursor_type = new_type; | 470 curve->cursor_type = new_type; |
462 | |
463 cursor = gdk_cursor_new(curve->cursor_type); | 471 cursor = gdk_cursor_new(curve->cursor_type); |
464 gdk_window_set_cursor(w->window, cursor); | 472 gdk_window_set_cursor(w->window, cursor); |
465 gdk_cursor_destroy(cursor); | 473 gdk_cursor_destroy(cursor); |
466 } | 474 } |
467 break; | 475 break; |
496 | 504 |
497 gtk_drawing_area_size(GTK_DRAWING_AREA(curve), width + RADIUS2, height + RADIUS2); | 505 gtk_drawing_area_size(GTK_DRAWING_AREA(curve), width + RADIUS2, height + RADIUS2); |
498 } | 506 } |
499 | 507 |
500 | 508 |
501 void xs_curve_reset(XSCurve *curve) | 509 static void xs_curve_update(XSCurve *curve) |
502 { | 510 { |
503 if (curve->ctlpoints) | |
504 g_free(curve->ctlpoints); | |
505 | |
506 curve->num_ctlpoints = 4; | |
507 curve->ctlpoints = g_malloc(curve->num_ctlpoints * sizeof(curve->ctlpoints[0])); | |
508 | |
509 GET_X(0) = curve->min_x; | |
510 GET_Y(0) = curve->min_y; | |
511 | |
512 GET_X(1) = curve->min_x; | |
513 GET_Y(1) = curve->min_y; | |
514 | |
515 GET_X(2) = curve->max_x; | |
516 GET_Y(2) = curve->max_y; | |
517 | |
518 GET_X(3) = curve->max_x; | |
519 GET_Y(3) = curve->max_y; | |
520 | |
521 if (curve->pixmap) { | 511 if (curve->pixmap) { |
522 gint width, height; | 512 gint width, height; |
523 | 513 |
524 width = GTK_WIDGET(curve)->allocation.width - RADIUS2; | 514 width = GTK_WIDGET(curve)->allocation.width - RADIUS2; |
525 height = GTK_WIDGET(curve)->allocation.height - RADIUS2; | 515 height = GTK_WIDGET(curve)->allocation.height - RADIUS2; |
526 xs_curve_draw(curve, width, height); | 516 xs_curve_draw(curve, width, height); |
527 } | 517 } |
528 } | 518 } |
529 | 519 |
530 | 520 |
531 void xs_curve_set_range(XSCurve *curve, gfloat min_x, gfloat max_x, gfloat min_y, gfloat max_y) | 521 void xs_curve_reset(XSCurve *curve) |
522 { | |
523 if (curve->ctlpoints) | |
524 g_free(curve->ctlpoints); | |
525 | |
526 curve->nctlpoints = 4; | |
527 curve->ctlpoints = g_malloc(curve->nctlpoints * sizeof(curve->ctlpoints[0])); | |
528 | |
529 GET_X(0) = curve->min_x; | |
530 GET_Y(0) = curve->min_y; | |
531 GET_X(1) = curve->min_x; | |
532 GET_Y(1) = curve->min_y; | |
533 | |
534 GET_X(2) = curve->max_x; | |
535 GET_Y(2) = curve->max_y; | |
536 GET_X(3) = curve->max_x; | |
537 GET_Y(3) = curve->max_y; | |
538 | |
539 xs_curve_update(curve); | |
540 } | |
541 | |
542 | |
543 void xs_curve_set_range(XSCurve *curve, gfloat min_x, gfloat min_y, gfloat max_x, gfloat max_y) | |
532 { | 544 { |
533 curve->min_x = min_x; | 545 curve->min_x = min_x; |
534 curve->max_x = max_x; | 546 curve->max_x = max_x; |
547 | |
535 curve->min_y = min_y; | 548 curve->min_y = min_y; |
536 curve->max_y = max_y; | 549 curve->max_y = max_y; |
537 | 550 |
538 xs_curve_size_graph(curve); | 551 xs_curve_size_graph(curve); |
539 xs_curve_reset(curve); | 552 xs_curve_reset(curve); |
540 } | 553 } |
541 | 554 |
542 | 555 |
556 gboolean xs_curve_realloc_data(XSCurve *curve, gint npoints) | |
557 { | |
558 if (npoints != curve->nctlpoints) { | |
559 curve->nctlpoints = npoints; | |
560 curve->ctlpoints = (t_xs_point *) g_realloc(curve->ctlpoints, | |
561 curve->nctlpoints * sizeof(*curve->ctlpoints)); | |
562 | |
563 if (curve->ctlpoints == NULL) | |
564 return FALSE; | |
565 } | |
566 | |
567 return TRUE; | |
568 } | |
569 | |
570 | |
571 void xs_curve_get_data(XSCurve *curve, t_xs_point ***points, gint **npoints) | |
572 { | |
573 *points = &(curve->ctlpoints); | |
574 *npoints = &(curve->nctlpoints); | |
575 } | |
576 | |
577 | |
578 gboolean xs_curve_set_points(XSCurve *curve, t_xs_int_point *points, gint npoints) | |
579 { | |
580 gint i; | |
581 | |
582 if (!xs_curve_realloc_data(curve, npoints + 4)) | |
583 return FALSE; | |
584 | |
585 GET_X(0) = curve->min_x; | |
586 GET_Y(0) = curve->min_y; | |
587 GET_X(1) = curve->min_x; | |
588 GET_Y(1) = curve->min_y; | |
589 | |
590 for (i = 0; i < npoints; i++) { | |
591 GET_X(i+2) = points[i].x; | |
592 GET_Y(i+2) = points[i].y; | |
593 } | |
594 | |
595 GET_X(npoints+2) = curve->max_x; | |
596 GET_Y(npoints+2) = curve->max_y; | |
597 GET_X(npoints+3) = curve->max_x; | |
598 GET_Y(npoints+3) = curve->max_y; | |
599 | |
600 xs_curve_update(curve); | |
601 return TRUE; | |
602 } | |
603 | |
604 | |
605 gboolean xs_curve_get_points(XSCurve *curve, t_xs_int_point **points, gint *npoints) | |
606 { | |
607 gint i, n; | |
608 | |
609 n = curve->nctlpoints - 4; | |
610 | |
611 *points = g_malloc(n * sizeof(t_xs_int_point)); | |
612 if (*points == NULL) | |
613 return FALSE; | |
614 | |
615 *npoints = n; | |
616 for (i = 2; i < curve->nctlpoints - 2; i++) { | |
617 (*points)[i].x = GET_X(i); | |
618 (*points)[i].y = GET_Y(i); | |
619 } | |
620 | |
621 return TRUE; | |
622 } | |
623 | |
624 | |
543 GtkWidget *xs_curve_new(void) | 625 GtkWidget *xs_curve_new(void) |
544 { | 626 { |
545 return gtk_type_new(xs_curve_get_type()); | 627 return gtk_type_new(xs_curve_get_type()); |
546 } | 628 } |
547 | 629 |
561 if (curve->ctlpoints) | 643 if (curve->ctlpoints) |
562 g_free(curve->ctlpoints); | 644 g_free(curve->ctlpoints); |
563 | 645 |
564 (*GTK_OBJECT_CLASS(parent_class)->finalize) (object); | 646 (*GTK_OBJECT_CLASS(parent_class)->finalize) (object); |
565 } | 647 } |
566 |